From 9ff6a34edaecda2a36d0e157c582ed0bf35caa76 Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Thu, 3 May 2012 14:30:40 +0200 Subject: [PATCH 0001/3075] Pushing uncommitted footprint --- contribute/bug-reporting-guide.md | 4 ++ contribute/git-guide.md | 4 ++ contribute/index.md | 70 +++++++++++++++++++++++++++++++ contribute/partest-guide.md | 4 ++ contribute/workflow.md | 4 ++ 5 files changed, 86 insertions(+) create mode 100644 contribute/bug-reporting-guide.md create mode 100644 contribute/git-guide.md create mode 100644 contribute/index.md create mode 100644 contribute/partest-guide.md create mode 100644 contribute/workflow.md diff --git a/contribute/bug-reporting-guide.md b/contribute/bug-reporting-guide.md new file mode 100644 index 0000000000..33640bcd47 --- /dev/null +++ b/contribute/bug-reporting-guide.md @@ -0,0 +1,4 @@ +--- +layout: page +title: Bug Reporting +--- \ No newline at end of file diff --git a/contribute/git-guide.md b/contribute/git-guide.md new file mode 100644 index 0000000000..a66fb33190 --- /dev/null +++ b/contribute/git-guide.md @@ -0,0 +1,4 @@ +--- +layout: page +title: Using git +--- \ No newline at end of file diff --git a/contribute/index.md b/contribute/index.md new file mode 100644 index 0000000000..b11a73bcbf --- /dev/null +++ b/contribute/index.md @@ -0,0 +1,70 @@ +--- +layout: page +title: Contribute +--- + +- This page should contain the introduction as mentioned in the Scala Doc team google document +- Subpages or subsections for contributing for each project (i.e. how to find tickets/features to work on) +- Building and contributing code (contributor's workflow) + - link to a proper git etiquette page + - link to CLA + - how to run and use partest + - compiler page (links to compiler-related docs i.e. reflection/macros/compiler-plugin guides, links to compiler internal videos, and useful info from wiki) (or should this go on docs.scala-lang?) +- Link to how to make a bug report + +The Scala programming langauge is an open source project from École +Polytechnique Fédérale de Lausanne (EPFL) in Switzerland. The source of the +compiler and libraries is hosted on [github](http://github.com/scala/scala). + +Some aspects of the language are easier to contribute to than others-- the +compiler, for example, is arguably the most difficult part of the Scala +project to successfully submit patches to. + +If you're interested in joining our community and contributing to the project, +start simple-- often Scaladoc (Scala's javadoc-like tool, Example: [Scala +Standard Library API](www.scala-lang.org/api/current/index.html#package)) is +the best place to get started. + + + EPFL Typesafe Stack + _______________ ___________ + | | | | + | stdlib | | Akka | + | compiler | | Play! | + | scaladoc | | SBT | + | documentation | | .... | + |_______________| |___________| + + +## Testing + +Partest how-tos. + +### Lukas's new build machine + +Link, needs repo name and github username and builds/tests for you. + +## Community tickets + +- for scaladoc +- for the stdlib +- for the compiler +- for the doc site + +## Process + +"gitting stuff done" document. + +Where to ask questions. How-tos to mailing list, discussion pertaining to a +specific ticket on the issue tracker. + +## CLA + +## FAQ + +### OSX + +### Linux + +### Windows + diff --git a/contribute/partest-guide.md b/contribute/partest-guide.md new file mode 100644 index 0000000000..1b3c098cca --- /dev/null +++ b/contribute/partest-guide.md @@ -0,0 +1,4 @@ +--- +layout: page +title: Running the Test Suite +--- \ No newline at end of file diff --git a/contribute/workflow.md b/contribute/workflow.md new file mode 100644 index 0000000000..89c71102a9 --- /dev/null +++ b/contribute/workflow.md @@ -0,0 +1,4 @@ +--- +layout: page +title: Contributor's Workflow +--- \ No newline at end of file From fc99948bd01ccad7310366e17a16d3a75b4a3c94 Mon Sep 17 00:00:00 2001 From: ingoem Date: Thu, 27 Sep 2012 11:45:57 +0200 Subject: [PATCH 0002/3075] Some work on the contribute section --- contribute/git-guide.md | 76 ++++++++++++++++++++++++++++++++++++++++- contribute/index.md | 61 +++++++++++++++++++++++++++++---- 2 files changed, 130 insertions(+), 7 deletions(-) diff --git a/contribute/git-guide.md b/contribute/git-guide.md index a66fb33190..2e173ec7ec 100644 --- a/contribute/git-guide.md +++ b/contribute/git-guide.md @@ -1,4 +1,78 @@ --- layout: page title: Using git ---- \ No newline at end of file +--- + +This is a step-by-step guide on how to use [git](http://git-scm.com/) and [github](http://github.com/) if you want to contribute to the Scala project. If you are new to git, make yourself familiar first. We recommend the [Git Pro]()http://git-scm.com/book/en/) online book. + +### Signup + +First create an account on [github](http://github.com/). You can also use your existing account, of course. + +### Fork + +Now, go to [https://github.com/scala/scala]() and click the "Fork" button at the top of the page. + +![image](images/fork.png) + +If everything went okay, you will be redirected to your own fork at `https://github.com/username/scala`, where `username` is your github user name. Make sure you read [http://help.github.com/fork-a-repo/](), which covers some of the things that will follow below. + +### Clone + +Clone your repository. Run the following on the command line: + + $ git clone https://github.com/username/scala + +This will create a local directory called `scala`, which contains a clone of the remote repository. + +### Branch + +Before you start making changes, always create your own branch. Never work on the `master` branch. Think of a name that describes the changes you plan on doing. Use a prefix that describes the nature of your change. There are essentially two kinds of changes: bug fixes and new features. + + - For bug fixes, use `issue/NNNN` for bug NNNN from the [Scala issue tracker](https://issues.scala-lang.org/). + - For a new feature use `topic/XXX` for feature XXX. + +Use feature names that make sense in the context of the whole Scala project and not just to you personally. For example, if you work on diagrams in Scaladoc, use `topic/scaldoc-diagrams` instead of just `topic/diagrams`. + +For your initial contribution, try work on something manageable (TODO: link to the subproject overview page). + +Now, it's time to create your branch. Run the following on the command line + + $ git checkout -b topic/XXX + +If you are new to git and branching, please read the [Branching Chapter](http://git-scm.com/book/en/Git-Branching) in the Git Pro book. + +### Change + +Now, you are ready to make changes ot the code base. The [Git Basics](http://git-scm.com/book/en/Git-Basics) chapter in the Git online book covers most of the basic workflow during this stage. + +TODO: refer to other development stuff, partest and so on. + +### Sync and Rebase + +Before you can submit your patch, make sure that your commit structure is clean. We won't accept pull requests for bug fixes that have more than one commit. For features, it is okay to have several commits, but all tests need to pass after every single commit. To clean up your commit structure, you want to [rewrite history](http://git-scm.com/book/en/Git-Branching-Rebasing) using `git rebase` so your commits are against the latest revision of `master`. + +Occassionally, you also want to sync with `master` so you don't fall behind too much. Otherwise, creating a clean pull request can become a lot of work. It is often a good idea to use `git rebase` instead of `git merge` to stay on top of `master` and keep a linear commit structure (TODO: do we actually REQUIRE this???). Read more about this approach [here](http://git-scm.com/book/en/Git-Branching-Rebasing). + +### Push + +For now, you might have committed your changes only locally (or maybe you have pushed your changes already to your fork on github because you want others to see it). Once you are satisfied with your work, synced with `master` and cleaned up your commits you are ready to submit a patch to the central Scala repository. First, make sure you have pushed all of your local changes to your fork on github. + + $ git push username + # This pushes all of your local branches to your fork on github. + +Again, `username` stands for your github user name. + +### Submit pull request + +Now it's time to send your changes to the Scala project for review. To do so, you ask for your changes to be pulled into the main repository by submitting a pull request. Go to your own Scala project page at `https://github.com/username/scala` and switch to the branch that contains your changes. + +![image](images/switchbranch.png) + +Then click on the "Pull Request" button at the top. + +![image](images/pullrequest.png) + +The github help page at [http://help.github.com/send-pull-requests/]() covers sending pull requests in more detail. Make sure you submit your request against the right branch. Strictly follow our [Pull Request policy](https://github.com/scala/scala/wiki/Pull-Request-Policy). + +A pull request is rarely accepted right away, so don't be depressed if the reviewer of your pull request will reject it or asks you to make additional changes before your request can be eventually accepted into the main repository. diff --git a/contribute/index.md b/contribute/index.md index b11a73bcbf..9f90154c85 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -26,6 +26,14 @@ Standard Library API](www.scala-lang.org/api/current/index.html#package)) is the best place to get started. +## Overview of the Scala Ecosystem + +TODO: I feel this section belongs somewhere else and should be linked here. + +[Scala Project](http://scala-lang.org) + +[Typesafe Stack](http://typesafe.com/stack) + EPFL Typesafe Stack _______________ ___________ | | | | @@ -34,21 +42,42 @@ the best place to get started. | scaladoc | | SBT | | documentation | | .... | |_______________| |___________| + + + +## Basic Workflow + +The Scala project, including the compiler, standard library and Scaladoc is hosted on [https://github.com/scala/scala](). As usual on github, developers work in personal forks that are merged into the main repository via pull request after having successfully completed a review process. As a contributor, your basic workflow is as follows: + + 1. [Fork](https://help.github.com/articles/fork-a-repo) the [Scala Project](https://github.com/scala/scala) + - Create a [topic branch](http://git-scm.com/book/en/Git-Branching-Branching-Workflows#Topic-Branches) + - Fix a [bug](https://issues.scala-lang.org/secure/IssueNavigator.jspa?reset=true&jqlQuery=labels+%3D+community), implement a feature + - Push your changes to your fork on github + - Submit [pull request](https://help.github.com/articles/using-pull-requests) + - Work with a reviewer on [getting your request merged](https://github.com/scala/scala/wiki/Pull-Request-Policy) + - Celebrate! +Read our [Git Commit Guide](git-guide.html) for details. + +## Building + +The Scala compiler and libraries are built using Ant. Read the [README](https://github.com/scala/scala/blob/master/README.rst) on how to build, test and create a distribution. ## Testing -Partest how-tos. +We maintain an extensive test suite that is run via our parallel testing tool `partest`. Read our [Partest Guide](partest-guide.html) for details. ### Lukas's new build machine Link, needs repo name and github username and builds/tests for you. -## Community tickets +## What to work on -- for scaladoc -- for the stdlib -- for the compiler +If you want to become a contributor but you don't know what to work on, here are a few ideas. Generally, it is a good idea to start with fixing bugs! To get some idea, head over to our [Scala issue tracker](https://issues.scala-lang.org/) and search for some unresolved bugs assigned to the community or click [here](https://issues.scala-lang.org/secure/IssueNavigator.jspa?reset=true&jqlQuery=labels+%3D+community) for a direct link. Here is a breakdown into different subprojects: + + - [Scaladoc](https://issues.scala-lang.org/secure/IssueNavigator!executeAdvanced.jspa?jqlQuery=labels+%3D+scaladoc+and+labels+%3D+community&runQuery=true&clear=true) +- [Standard Library](https://issues.scala-lang.org/secure/IssueNavigator!executeAdvanced.jspa?jqlQuery=labels+%3D+community+and+labels+%3D+library&runQuery=true&clear=true) +- [Compiler](https://issues.scala-lang.org/secure/IssueNavigator!executeAdvanced.jspa?jqlQuery=labels+%3D+community+and+labels+%3D+compiler&runQuery=true&clear=true) - for the doc site ## Process @@ -58,8 +87,28 @@ Link, needs repo name and github username and builds/tests for you. Where to ask questions. How-tos to mailing list, discussion pertaining to a specific ticket on the issue tracker. -## CLA +## Contributor's License Agreement + +Before we can accept your pull request you have to sign our Contributor's License Agreement (CLA). + +TODO: Heather + +## Compiler Internals + +The files below are recordings of code walk-through sessions by Martin Odersky about the Scala compiler internals. Some of the information is somewhat outdated, but the clips are still a good introduction to some parts of the compiler architecture. + - [Scala Internals 2008-10-29 (Symbols 1)](http://www.scala-lang.org/sites/default/files/martin_ordersky_scala_internals_2008-10-29.avi) + + Handling of Symbols in the Scala compiler: some details on the symtab subdir, Symbols, Definitions, StdNames, Types (Lazy Types). + + - [Scala Internals 2008-11-05 (Symbols 2)](http://www.scala-lang.org/sites/default/files/martin_ordersky_scala_internals_2008-11-05.avi) + + Handling of Symbols part deux: more information on Symbols, Flags, Definitions. + + - [Scala Internals 2009-03-04 (Types)](http://www.scala-lang.org/sites/default/files/martin_ordersky_scala_internals_2009-03-04.avi) + + A detailed explanation about how types are represented and manipulated within the Scala compiler: data structures, manipulations of types, coding conventions (audio is not perfect, but intelligible). + ## FAQ ### OSX From 02337f4add685cbe0155d8e7e0f12ea29e536aaa Mon Sep 17 00:00:00 2001 From: ingoem Date: Thu, 27 Sep 2012 16:42:23 +0200 Subject: [PATCH 0003/3075] Add partest guide --- contribute/partest-guide.md | 64 ++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/contribute/partest-guide.md b/contribute/partest-guide.md index 1b3c098cca..e681c569fe 100644 --- a/contribute/partest-guide.md +++ b/contribute/partest-guide.md @@ -1,4 +1,66 @@ --- layout: page title: Running the Test Suite ---- \ No newline at end of file +--- + +Partest is a custom parallel testing tool that we use to run the test suite for the Scala compiler and library. Go the scala project folder from your local checkout and run it via `ant` or standalone as follows. + +## Using ant + +The test suite can be run by using ant from the command line: + + $ ant test.suite + +## Standalone + +There are launch scripts `partest` and `partest.bat` in the `test` folder of the scala project. To have partest run failing tests only and print details about test failures to the console, you can use + + ./test/partest --show-diff --show-log --failed + +You can get a summary of the usage by running partest without arguments. + +* Most commonly you want to invoke partest with an option that tells it which part of the tests to run. For example `--all`, `--pos`, `--neg` or `--run`. +* You can test individual files by specifying individual test files (`.scala` files) as options. Several files can be tested if they are from the same category, e.g., `pos`. +* You can enable output of log and diff using the `-show-log` and `-show-diff` options. +* If you get into real trouble, and want to find out what partest does, you can run it with option `--verbose`. This info is useful as part of bug reports. +* Set custom path from where to load classes: `-classpath ` and `-buildpath `. +* You can use the `SCALAC_OPTS` environment variable to pass command line options to the compiler. +* You can use the `JAVA_OPTS` environment variable to pass command line options to the runner (e.g., for `run/jvm` tests). +* The launch scripts run partest as follows: + + scala -cp scala.tools.partest.nest.NestRunner + + Partest classes from a `quick` build, e.g., can be found in `./build/quick/classes/partest/`. + + Partest will tell you where it loads compiler/library classes from by adding the `partest.debug` property: + + scala -Dpartest.debug=true -cp scala.tools.partest.nest.NestRunner + + + +## ScalaCheck tests + +Tests that depend on [ScalaCheck](https://github.com/rickynils/scalacheck) can be added under folder `./test/files/scalacheck`. A sample test: + + import org.scalacheck._ + import Prop._ + + object Test { + val prop_ConcatLists = property{ (l1: ListInt, l2: ListInt) => + l1.size + l2.size == (l1 ::: l2).size + } + + val tests = List(("prop_ConcatLists", prop_ConcatLists)) + } + +## Troubleshooting + +### Windows + +Some tests might fail because line endings in the `.check` files and the produced results do not match. In that case, set either + + git config core.autocrlf false + +or + + git config core.autocrlf input \ No newline at end of file From 9ea42c156a8025f1a5d436d390586eca4422a33e Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 1 Mar 2013 16:41:26 +0100 Subject: [PATCH 0004/3075] first 1.5 steps of the hacker guide --- contribute/01-post.png | Bin 0 -> 172693 bytes contribute/03-fork.png | Bin 0 -> 46172 bytes contribute/hacker-guide.md | 106 +++++++++++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 contribute/01-post.png create mode 100644 contribute/03-fork.png create mode 100644 contribute/hacker-guide.md diff --git a/contribute/01-post.png b/contribute/01-post.png new file mode 100644 index 0000000000000000000000000000000000000000..cef3dcaa46d8d4206f3b601ff7157c127d7eb55a GIT binary patch literal 172693 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 V{he5NlyEMeCkpEFC9+1o{{!U6U)2Br literal 0 HcmV?d00001 diff --git a/contribute/03-fork.png b/contribute/03-fork.png new file mode 100644 index 0000000000000000000000000000000000000000..abf86df0199e4d59dc27bbf4d0c2e93d976f1a66 GIT binary patch literal 46172 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 Date: Fri, 1 Mar 2013 18:26:56 +0100 Subject: [PATCH 0005/3075] "Contribute" landing page and sketches for two pages: - bug reporting - documentation contributions --- contribute/bug-reporting-guide.md | 53 ++++++++++++++++- contribute/documentation.md | 29 ++++++++++ contribute/index.md | 94 +++++++++++++++++++++++-------- contribute/scala-fame.md | 9 +++ 4 files changed, 162 insertions(+), 23 deletions(-) create mode 100644 contribute/documentation.md create mode 100644 contribute/scala-fame.md diff --git a/contribute/bug-reporting-guide.md b/contribute/bug-reporting-guide.md index 33640bcd47..a60fb15b07 100644 --- a/contribute/bug-reporting-guide.md +++ b/contribute/bug-reporting-guide.md @@ -1,4 +1,55 @@ --- layout: page title: Bug Reporting ---- \ No newline at end of file +--- + +# Reporting bugs to the Scala project + +The Scala project tracker is located at: + +> [http://issues.scala-lang.org](http://issues.scala-lang.org) + + + diff --git a/contribute/documentation.md b/contribute/documentation.md new file mode 100644 index 0000000000..05b2455a5f --- /dev/null +++ b/contribute/documentation.md @@ -0,0 +1,29 @@ +--- +layout: page +title: Documentation Contributions +--- +# Contributing documentation to the Scala project + +TODO + + diff --git a/contribute/index.md b/contribute/index.md index 9f90154c85..a92c5f37cc 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -2,8 +2,66 @@ layout: page title: Contribute --- +# Contributing to the Scala project + +The Scala programming langauge is an open source project with a very +diverse community, where people from all over the world contribute their work, +with everyone benefitting from friendly help and advice, and +kindly helping others in return. So why not join the Scala community and help +everyone make things better? + +The following are typical questions you might ask when first contributing to Scala. +If you have other questions not addressed here, feel free to ask on the [scala-internals mailing list](http://groups.google.com/group/scala-internals). + +
+ +### I found something that doesn't work as expected. How to file a bug report? + +[The reporting bugs page](bug-reporting-guide.html) describes the steps to take when you find something that doesn't work +as expected. Filing in a good bug report increases the chances the ticket is fixed quickly. + +
+ +### Why contribute a patch to Scala? + +Just to name a few common reasons: + - contributing a patch is the best way to make sure your desired changes will be available in the next Scala version + - Scala is written in Scala, so going through the source code and patching it will improve your Scala-fu + - last but not least, you will make it into the [Scala Contribuitor Hall of Fame](scala-fame.html). + +
+ +### I'd like to start hacking the Scala project, how to find something to work on? + +Depending on your skillset, you may want to contribute documentation and/or code. Documentation has always been very +appreciated work in the Scala community, as most code contributions tend to be quite scarce in explanations of how +things work and how everyone else is supposed to use them. To contribute documentation, have a look at the +[documentation page](documentation.html). + +The main Scala project consists of the standard Scala library, the Scala reflection and macros library, +the Scala compiler and the Scaladoc tool. This means there's plenty to choose from when deciding what to work on. +Typically the scaladoc tool provides a low entry point for new committers, so it is a good first step into contributing. + +On the Scala bug tracker you will find many bugs that are [marked as good starting points to contributing ("community" bugs)](https://issues.scala-lang.org/secure/IssueNavigator.jspa?requestId=12111) or [that are not currently assigned](https://issues.scala-lang.org/secure/IssueNavigator.jspa?requestId=12112) and that you could pick up. Once you decided on a ticket to look at, see the next step on how to proceed further. + +
+ +### I have this idea that I'd like to add to Scala, how do I start? + +The first step to making a change is to discuss it with the community at large, to make sure everyone agrees on the idea +and on the implementation plan. Starting point ("community") bugs are usually uncontroversial, so you can jump right +ahead to hacking the scala source tree and filing a pull request. For larger changes it is best to announce the change +on the [scala-internals](http://groups.google.com/group/scala-internals) mailing list and get developer feedback. For really complex changes, a [Scala Improvement Process (SIP)](http://docs.scala-lang.org/sips/) document might be required, but the first step is always to discuss it on the mailing list. + +Contributions, big or small, simple or complex, controversial or undisputed, need to materialize as patches against +the Scala project source tree. The [hacker guide](hacker-guide.html) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. + +
+ + \ No newline at end of file diff --git a/contribute/scala-fame.md b/contribute/scala-fame.md new file mode 100644 index 0000000000..75317be820 --- /dev/null +++ b/contribute/scala-fame.md @@ -0,0 +1,9 @@ +--- +layout: page +title: Scala Contribuitor Hall of Fame +--- +# Scala Hall of Fame + +A big thank you to everyone who contributed to: + - [the Scala library and compiler](https://github.com/scala/scala/contributors) + - [the Scala documentation website](https://github.com/scala/scala.github.com/contributors) \ No newline at end of file From b09e5f106986a3fafdd42d5ad0ae0f61982b58a5 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 1 Mar 2013 18:29:10 +0100 Subject: [PATCH 0006/3075] 1.5 more sections --- contribute/02-post.png | Bin 0 -> 114529 bytes contribute/hacker-guide.md | 153 ++++++++++++++++++++++++++++++++----- 2 files changed, 135 insertions(+), 18 deletions(-) create mode 100644 contribute/02-post.png diff --git a/contribute/02-post.png b/contribute/02-post.png new file mode 100644 index 0000000000000000000000000000000000000000..533ac99538d153d433129e59513a708d02fcc429 GIT binary patch literal 114529 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 Date: Fri, 1 Mar 2013 19:57:46 +0100 Subject: [PATCH 0007/3075] tentative fin --- contribute/04-submit.png | Bin 0 -> 166407 bytes contribute/05-review.png | Bin 0 -> 29682 bytes contribute/hacker-guide.md | 116 ++++++++++++++++++++++++++++++++++++- 3 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 contribute/04-submit.png create mode 100644 contribute/05-review.png diff --git a/contribute/04-submit.png b/contribute/04-submit.png new file mode 100644 index 0000000000000000000000000000000000000000..80acc36cf93e380c7257203ba879ef1636c82641 GIT binary patch literal 166407 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

f?AQ{Dupipdlg;C}}=T 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

5V-fPj1J=6v-5Ui*9vLJ^IReprT1O{yZE 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 z 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 BSkM3f literal 0 HcmV?d00001 diff --git a/contribute/05-review.png b/contribute/05-review.png new file mode 100644 index 0000000000000000000000000000000000000000..330cb519ac2c6945b9e480262568025fe49b7c1f GIT binary patch literal 29682 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 literal 0 HcmV?d00001 diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 298ac6a307..9805ad8795 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -136,8 +136,6 @@ with your hardware). [exec] Resolving [943cd5c8802b2a3a64a010efb86ec19bac142e40/lib/ant/ant-contrib.jar] ... - ... - ... pack.bin: [mkdir] Created dir: /Users/xeno_by/Projects/scala/build/pack/bin @@ -188,6 +186,7 @@ reproducible by throwing together a simple test and feeding it into the Scala di } 17:27 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scalac Test.scala 17:28 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scala Test + 1%n1 ### Implement ### @@ -219,5 +218,118 @@ exclusively as a folklore. However the situation is steadily improving. Here are * [scala-internals](http://groups.google.com/group/scala-internals), a mailing list which hosts discussions about the core internal design and implementation of the Scala system. +### Interlude ### + +To fix [the bug I'm interested in](https://issues.scala-lang.org/browse/SI-6725) I've tracked the `StringContext.f` interpolator +down to a macro implemented in `MacroImplementations.scala`. There I noticed that the interpolator only processes conversions, +but not tokens like `%n`. Looks like an easy fix. + + 18:44 ~/Projects/scala/sandbox (ticket/6725)$ git diff + diff --git a/src/compiler/scala/tools/reflect/MacroImplementations.scala b/src/compiler/scala/tools/ + index 002a3fce82..4e8f02084d 100644 + --- a/src/compiler/scala/tools/reflect/MacroImplementations.scala + +++ b/src/compiler/scala/tools/reflect/MacroImplementations.scala + @@ -117,7 +117,8 @@ abstract class MacroImplementations { + if (!strIsEmpty) { + val len = str.length + while (idx < len) { + - if (str(idx) == '%') { + + def notPercentN = str(idx) != '%' || (idx + 1 < len && str(idx + 1) != 'n') + + if (str(idx) == '%' && notPercentN) { + bldr append (str substring (start, idx)) append "%%" + start = idx + 1 + } + +After I applied the fix and running `ant`, my simple test case in `sandbox/Test.scala` started working! + + 18:51 ~/Projects/scala/sandbox (ticket/6725)$ cd .. + 18:51 ~/Projects/scala (ticket/6725)$ ant + Buildfile: /Users/xeno_by/Projects/scala/build.xml + + ... + + quick.comp: + [scalacfork] Compiling 1 file to /Users/xeno_by/Projects/scala/build/quick/classes/compiler + [propertyfile] Updating property file: /Users/xeno_by/Projects/scala/build/quick/classes/compiler/compiler.properties + [stopwatch] [quick.comp.timer: 6.588 sec] + + ... + + BUILD SUCCESSFUL + Total time: 18 seconds + + 18:51 ~/Projects/scala (ticket/6725)$ cd sandbox + 18:51 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scalac Test.scala + 18:51 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scala Test + 1 + 1 + ### Verify ### +Now to make sure that my fix doesn't break anything I need to run the test suite using the `partest` tool we wrote to test Scala. +Read up [the partest guide](/contribute/partest-guide.html) to learn the details about partest, but in a nutshell you can either +run `ant test` to go through the entire test suite (30+ minutes) or use wildcards to limit the tests to something manageable: + + 18:52 ~/Projects/scala/sandbox (ticket/6725)$ cd ../test + 18:56 ~/Projects/scala/test (ticket/6725)$ partest files/run/*interpol* + Testing individual files + testing: [...]/files/run/interpolationArgs.scala [ OK ] + testing: [...]/files/run/interpolationMultiline1.scala [ OK ] + testing: [...]/files/run/interpolationMultiline2.scala [ OK ] + testing: [...]/files/run/sm-interpolator.scala [ OK ] + testing: [...]/files/run/interpolation.scala [ OK ] + testing: [...]/files/run/stringinterpolation_macro-run.scala [ OK ] + All of 6 tests were successful (elapsed time: 00:00:08) + +### 4. Publish ### + +After development is finished, it's time to publish the code and submit your patch for discussion and potential inclusion into Scala. +In a nutshell this involves: 1) making sure that your code and commit messages are of high quality, 2) clicking a few buttons in the +Github interface, 3) assigning one or more reviewers which will look through your pull request. Now all that in more details. + +### Commit ### + +The [Git Basics](http://git-scm.com/book/en/Git-Basics) chapter in the Git online book covers most of the basic workflow during this stage. +There are two things you should know here: + +1) Commit messages are frequently the only way to communicate with the authors of the code written a few years ago. Therefore, we give them +big importance. Be creative and eloquent - the more context your provide about the change you've introduced, the bigger the probability that +some future maintainer will understand you right. Consult [the pull request policy](https://github.com/scala/scala/wiki/Pull-Request-Policy) +for more information about the desired style of your commits. + +2) Clean history is also important. Therefore we won't accept pull requests for bug fixes that have more than one commit. +For features, it is okay to have several commits, but all tests need to pass after every single commit. To clean up your commit structure, +you want to [rewrite history](http://git-scm.com/book/en/Git-Branching-Rebasing) using `git rebase` so your commits are against +the latest revision of `master`. + +Once you are satisfied with your work, synced with `master` and cleaned up your commits you are ready to submit a patch to the central Scala repository. Before proceeding make sure you have pushed all of your local changes to your fork on Github. + + 19:22 ~/Projects/scala/test (ticket/6725)$ git add ../src/compiler/scala/tools/reflect/MacroImplementations.scala + 19:22 ~/Projects/scala/test (ticket/6725)$ git commit + [ticket/6725 3c3098693b] SI-6725 `f` interpolator now supports %n tokens + 1 file changed, 2 insertions(+), 1 deletion(-) + 19:34 ~/Projects/scala/test (ticket/6725)$ git push origin ticket/6725 + Username for 'https://github.com': xeno-by + Password for 'https://xeno-by@github.com': + Counting objects: 15, done. + Delta compression using up to 8 threads. + Compressing objects: 100% (8/8), done. + Writing objects: 100% (8/8), 1.00 KiB, done. + Total 8 (delta 5), reused 0 (delta 0) + To https://github.com/xeno-by/scala + * [new branch] ticket/6725 -> ticket/6725 + +### Submit ### + +This part is very easy and enjoyable. Navigate to your branch in Github (for me it was `https://github.com/xeno-by/scala/tree/ticket/6725`) +and click the pull request button to submit your patch as a pull request to Scala. If you've never submitted patches to Scala, you will +need to sign the contributor license agreement, which [can be done online](http://typesafe.com/contribute/cla/scala) within a few minutes. + +![Submit a pull request](/contribute/04-submit.png) + +### Discuss ### + +After the pull request has been submitted, you need to pick a reviewer (probably, the person you've contacted in the beginning of your +workflow) and be ready to elaborate and adjust your patch if necessary. I picked Martin, because we had such a nice chat on the mailing list: + +![Assign the reviewer](/contribute/05-review.png) From a541a62b5602dcd4aea855867ad3f03b7c1d65d3 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 1 Mar 2013 20:18:15 +0100 Subject: [PATCH 0008/3075] polishing the hacker guide --- contribute/hacker-guide.md | 62 ++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 9805ad8795..f5a4f8724e 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -10,12 +10,15 @@ to a nightly and, ultimately, to a production release of Scala incorporating you influence a programming language of your choice is amazing, and I'm excited to demonstrate that it's easier than one might think. +### The running example ### + I like string interpolation a lot. Doing debug prints with interpolators introduced in Scala 2.10.0 is so enjoyable that I often wonder how we ever lived without that feature. However there's an annoying issue which I occasionally stumble upon: the formatting string interpolator `f` [does not support](https://issues.scala-lang.org/browse/SI-6725) new line tokens `%n`. I could go the mailing list, ask to fix this bug and then indefinitely wait for the fix. Or I could instead patch Scala myself and get the fix in a subsequent release (nightly builds get produced, well, every -night, minor releases are pumped every few months and major releases happen once a year). Let's get to work! +night, minor releases are pumped every few months and major releases happen once a year). The latter option sounds cool, so let's see +how it works! ### 1. Connect ### @@ -47,7 +50,7 @@ list of people (Github usernames and real-life names) and their specialties: documentation: @heathermiller (Heather Miller) cps: @TiarkRompf (Tiark Rompf) -Martin is the one who submitted the string interpolation proposal and implemented this language features for Scala 2.10.0. +Martin is the one who submitted the string interpolation proposal and implemented this language feature for Scala 2.10.0. (TODO: how to choose a mailing list) Therefore now I'm going to [the scala-user mailing list](http://groups.google.com/group/scala-user) and will post a topic about my issue. Note that I put Martin in the cc list of the email. If I didn't do that, he would probably miss it in a bunch @@ -57,19 +60,19 @@ of emails, which get posted to scala-user every day. ![Response from Martin](/contribute/02-post.png) -Now when I have an approval of the feature's author, it makes sense to start doing something. +Now when I have the approval of the feature's author, I'll get to work! ### 2. Set up ### -Hacking Scala begins with creating a branch for your work item. In our workflow we use [Git](http://git-scm.com/) -and [GitHub](http://github.com/). This section of the guide provides a short walkthrough on how to use them. -If you are new to Git, it might make sense to familiarize with it first. We recommend the [Git Pro](http://git-scm.com/book/en/) +Hacking Scala begins with creating a branch for your work item. To develop Scala we use [Git](http://git-scm.com/) +and [GitHub](http://github.com/). This section of the guide provides a short walkthrough, but if you are new to Git, +it probably makes sense to familiarize with Git first. We recommend the [Git Pro](http://git-scm.com/book/en/) online book. ### Fork ### Log into [GitHub](http://github.com/), go to [https://github.com/scala/scala](https://github.com/scala/scala) and click the `Fork` -button at the top of the page. This will create your own copy of our repository that will serve as a scratchpad for your experiments. +button at the top of the page. This will create your own copy of our repository that will serve as a scratchpad for your hackings. If you're new to Git, don't be afraid of messing it up - there is no way you can corrupt our repository. ![Fork scala/scala](/contribute/03-fork.png) @@ -113,13 +116,13 @@ The next step after cloning your fork is setting up your machine to build Scala. [https://github.com/scala/scala/blob/master/README.rst](https://github.com/scala/scala/blob/master/README.rst), but here's the summary: * It is recommended to use Java `1.6` (not `1.7` or `1.8`, because they might cause occasional glitches). -* The build tool we use is `ant`. -* The build script runs the `pull-binary-libs.sh` script to download bootstrap libs. This requires `bash` and `curl`. -* The majority of our team works on Linux and OS X. +* The build tool is `ant`. +* The build runs the `pull-binary-libs.sh` script to download bootstrap libs. This requires `bash` and `curl`. +* The majority of our team works on Linux and OS X, so these operating systems are guaranteed to work. * Windows is supported, but it might have issues. Please report to [the issue tracker](https://issues.scala-lang.org/) if you encounter them. -In a nutshell, build Scala is as easy as running `ant` in the root of your clone. Be prepared to wait for a while - a full rebuild -takes 7+ minutes depending on your machine. Incremental builds are usually within 30-90 seconds range (again, your mileage might vary +In a nutshell, building Scala is as easy as running `ant` in the root of your clone. Be prepared to wait for a while - a full rebuild +takes 8+ minutes depending on your machine. Incremental builds are usually within 30-120 seconds range (again, your mileage might vary with your hardware). 16:50 ~/Projects/scala (ticket/6725)$ ant @@ -149,7 +152,7 @@ with your hardware). ### IDE ### -There's no single editor of choice to work with Scala sources, as there are trade-offs imposed by each available option. +There's no single editor of choice for working with Scala sources, as there are trade-offs associated with each available tool. Both Eclipse and Intellij IDEA have Scala plugins, which are known to work with our codebase. Here are [instructions for Eclipse](https://github.com/scala/scala/blob/master/src/eclipse/README.md) and @@ -158,7 +161,7 @@ navigation, refactoring and error reporting functionality as well as integrated of occasional sluggishness. On the other hand, lightweight editors such as Emacs, Sublime or jEdit provide unparalleled scriptability and performance, while -lacking semantic services and debugging. To address this shortcoming, one can integrate with ENSIME, +lacking semantic services and debugging. To address this shortcoming, they can integrate with ENSIME, a helper program, which hosts a resident Scala compiler providing some of the features implemented in traditional IDEs. However despite having significantly matured over the last year, its support for our particular codebase is still far from being great. @@ -168,12 +171,13 @@ Therefore it's hard to recommend a particular tool here, and your choice should ### 3. Hack ### When hacking on your topic of choice, you'll be modifying Scala, compiling it and testing it on relevant input files. -Typically you would want to first make sure that your changes work on a few small example and afterwards verify that nothing break -by running the comprehensive test suite. +Typically you would want to first make sure that your changes work on a small example and afterwards verify that nothing break +by running a comprehensive test suite. I'm going to start by creating a `sandbox` directory (this particular name doesn't bear any special meaning - it's just a tribute to -my first days in Scala team), which will hold a single test file and its compilation results. First I make sure that the bug is indeed -reproducible by throwing together a simple test and feeding it into the Scala distribution assembled by ant in `build/pack/bin`. +my first days in Scala team), which will hold a single test file and its compilation results. First I make sure that +[the bug](https://issues.scala-lang.org/browse/SI-6725) is indeed reproducible by throwing together a simple test and feeding it +into the Scala distribution assembled by ant in `build/pack/bin`. 17:25 ~/Projects/scala (ticket/6725)$ mkdir sandbox 17:26 ~/Projects/scala (ticket/6725)$ cd sandbox @@ -186,7 +190,7 @@ reproducible by throwing together a simple test and feeding it into the Scala di } 17:27 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scalac Test.scala 17:28 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scala Test - 1%n1 + 1%n1 // %n should've been replaced by a newline here ### Implement ### @@ -198,17 +202,17 @@ Here are also some tips & tricks that have proven useful in Scala development: try doing `ant clean build`. Due to the way how Scala compiles traits, if a trait changes, then it's sometimes not enough to recompile just that trait, but it might also be necessary to recompile its users. Ant is not smart enough to do that, which might lead to very strange errors. Full rebuilds fix the problem. Fortunately that's rarely necessary, because full rebuilds take significant time. -* Even on solid state drives packaging Scala distribution (i.e. creating jars from class files) is a non-trivial task. There are quite a few - people in our team, who do `ant quick.comp` instead of `ant` and then create custom scripts to launch Scala from `build/quick/classes`. +* Even on solid state drives packaging Scala distribution (i.e. creating jars from class files) is a non-trivial task. To save time here, + some people in our team do `ant quick.comp` instead of `ant` and then create custom scripts to launch Scala from `build/quick/classes`. * Don't underestimate the power of `print`. When starting with Scala, I spent a lot of time in the debugger trying to figure out how things work. However later I found out that print-based debugging is often more effective than jumping around. While it might be obvious - to some, I'd like to explicitly mention that it's useful to print stack traces to understand the flow of execution. + to some, I'd like to explicitly mention that it's also useful to print stack traces to understand the flow of execution. -Docs. Right, the docs. The documentation about internal workings of the compiler is scarce, and a lot of knowledge gets passed -exclusively as a folklore. However the situation is steadily improving. Here are the resources that might help: +Docs. Right, the docs. The documentation about internal workings of the compiler is scarce, and most of the knowledge is passed around +in the form of folklore. However the situation is steadily improving. Here are the resources that might help: * [Compiler internals videos by Martin Odersky](TODO) are quite dated, but still very useful. In this three-video - series Martin explains inner working of the part of the compiler, which has recently become Scala reflection API. + series Martin explains inner workings of the part of the compiler, which has recently become Scala reflection API. * [Reflection and Compilers by Martin Odersky](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Reflection-and-Compilers), a talk at Lang.NEXT 2012 in which Martin elaborates on the design of scalac and the reflection API. * [Reflection documentation](http://docs.scala-lang.org/overviews/reflection/overview.html) describes fundamental data structures that @@ -262,7 +266,7 @@ After I applied the fix and running `ant`, my simple test case in `sandbox/Test. 18:51 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scalac Test.scala 18:51 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scala Test 1 - 1 + 1 // no longer getting the %n here - it got transformed into a newline ### Verify ### @@ -293,13 +297,13 @@ The [Git Basics](http://git-scm.com/book/en/Git-Basics) chapter in the Git onlin There are two things you should know here: 1) Commit messages are frequently the only way to communicate with the authors of the code written a few years ago. Therefore, we give them -big importance. Be creative and eloquent - the more context your provide about the change you've introduced, the bigger the probability that -some future maintainer will understand you right. Consult [the pull request policy](https://github.com/scala/scala/wiki/Pull-Request-Policy) +big importance. Be creative and eloquent - the more context your provide for the change you've introduced, the bigger the probability that +some future maintainer will get you right. Consult [the pull request policy](https://github.com/scala/scala/wiki/Pull-Request-Policy) for more information about the desired style of your commits. 2) Clean history is also important. Therefore we won't accept pull requests for bug fixes that have more than one commit. For features, it is okay to have several commits, but all tests need to pass after every single commit. To clean up your commit structure, -you want to [rewrite history](http://git-scm.com/book/en/Git-Branching-Rebasing) using `git rebase` so your commits are against +you want to [rewrite history](http://git-scm.com/book/en/Git-Branching-Rebasing) using `git rebase` so that your commits are against the latest revision of `master`. Once you are satisfied with your work, synced with `master` and cleaned up your commits you are ready to submit a patch to the central Scala repository. Before proceeding make sure you have pushed all of your local changes to your fork on Github. From edc6f1520130fe52496f48109bf2fd2a1eb4fdb3 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 1 Mar 2013 20:19:06 +0100 Subject: [PATCH 0009/3075] removes the git guide - it's been subsumed by the hacker's guide --- contribute/git-guide.md | 78 ----------------------------------------- 1 file changed, 78 deletions(-) delete mode 100644 contribute/git-guide.md diff --git a/contribute/git-guide.md b/contribute/git-guide.md deleted file mode 100644 index 2e173ec7ec..0000000000 --- a/contribute/git-guide.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -layout: page -title: Using git ---- - -This is a step-by-step guide on how to use [git](http://git-scm.com/) and [github](http://github.com/) if you want to contribute to the Scala project. If you are new to git, make yourself familiar first. We recommend the [Git Pro]()http://git-scm.com/book/en/) online book. - -### Signup - -First create an account on [github](http://github.com/). You can also use your existing account, of course. - -### Fork - -Now, go to [https://github.com/scala/scala]() and click the "Fork" button at the top of the page. - -![image](images/fork.png) - -If everything went okay, you will be redirected to your own fork at `https://github.com/username/scala`, where `username` is your github user name. Make sure you read [http://help.github.com/fork-a-repo/](), which covers some of the things that will follow below. - -### Clone - -Clone your repository. Run the following on the command line: - - $ git clone https://github.com/username/scala - -This will create a local directory called `scala`, which contains a clone of the remote repository. - -### Branch - -Before you start making changes, always create your own branch. Never work on the `master` branch. Think of a name that describes the changes you plan on doing. Use a prefix that describes the nature of your change. There are essentially two kinds of changes: bug fixes and new features. - - - For bug fixes, use `issue/NNNN` for bug NNNN from the [Scala issue tracker](https://issues.scala-lang.org/). - - For a new feature use `topic/XXX` for feature XXX. - -Use feature names that make sense in the context of the whole Scala project and not just to you personally. For example, if you work on diagrams in Scaladoc, use `topic/scaldoc-diagrams` instead of just `topic/diagrams`. - -For your initial contribution, try work on something manageable (TODO: link to the subproject overview page). - -Now, it's time to create your branch. Run the following on the command line - - $ git checkout -b topic/XXX - -If you are new to git and branching, please read the [Branching Chapter](http://git-scm.com/book/en/Git-Branching) in the Git Pro book. - -### Change - -Now, you are ready to make changes ot the code base. The [Git Basics](http://git-scm.com/book/en/Git-Basics) chapter in the Git online book covers most of the basic workflow during this stage. - -TODO: refer to other development stuff, partest and so on. - -### Sync and Rebase - -Before you can submit your patch, make sure that your commit structure is clean. We won't accept pull requests for bug fixes that have more than one commit. For features, it is okay to have several commits, but all tests need to pass after every single commit. To clean up your commit structure, you want to [rewrite history](http://git-scm.com/book/en/Git-Branching-Rebasing) using `git rebase` so your commits are against the latest revision of `master`. - -Occassionally, you also want to sync with `master` so you don't fall behind too much. Otherwise, creating a clean pull request can become a lot of work. It is often a good idea to use `git rebase` instead of `git merge` to stay on top of `master` and keep a linear commit structure (TODO: do we actually REQUIRE this???). Read more about this approach [here](http://git-scm.com/book/en/Git-Branching-Rebasing). - -### Push - -For now, you might have committed your changes only locally (or maybe you have pushed your changes already to your fork on github because you want others to see it). Once you are satisfied with your work, synced with `master` and cleaned up your commits you are ready to submit a patch to the central Scala repository. First, make sure you have pushed all of your local changes to your fork on github. - - $ git push username - # This pushes all of your local branches to your fork on github. - -Again, `username` stands for your github user name. - -### Submit pull request - -Now it's time to send your changes to the Scala project for review. To do so, you ask for your changes to be pulled into the main repository by submitting a pull request. Go to your own Scala project page at `https://github.com/username/scala` and switch to the branch that contains your changes. - -![image](images/switchbranch.png) - -Then click on the "Pull Request" button at the top. - -![image](images/pullrequest.png) - -The github help page at [http://help.github.com/send-pull-requests/]() covers sending pull requests in more detail. Make sure you submit your request against the right branch. Strictly follow our [Pull Request policy](https://github.com/scala/scala/wiki/Pull-Request-Policy). - -A pull request is rarely accepted right away, so don't be depressed if the reviewer of your pull request will reject it or asks you to make additional changes before your request can be eventually accepted into the main repository. From ca55cb4757fa02c89bdd469ca4a66a0b2476b5a1 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 1 Mar 2013 20:20:17 +0100 Subject: [PATCH 0010/3075] removes the workflow page - it's been subsumed by the hacker's guide --- contribute/workflow.md | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 contribute/workflow.md diff --git a/contribute/workflow.md b/contribute/workflow.md deleted file mode 100644 index 89c71102a9..0000000000 --- a/contribute/workflow.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -layout: page -title: Contributor's Workflow ---- \ No newline at end of file From de59612fefb92a5e76c50594070e5d1cb297387e Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Sun, 3 Mar 2013 14:06:49 +0100 Subject: [PATCH 0011/3075] Fixing issues with images, formatting fixups, moving maintainers list into an include for future reuse --- contribute/01-post.png | Bin 172693 -> 0 bytes contribute/02-post.png | Bin 114529 -> 0 bytes contribute/03-fork.png | Bin 46172 -> 0 bytes contribute/04-submit.png | Bin 166407 -> 0 bytes contribute/05-review.png | Bin 29682 -> 0 bytes contribute/hacker-guide.md | 32 ++++++++------------------------ 6 files changed, 8 insertions(+), 24 deletions(-) delete mode 100644 contribute/01-post.png delete mode 100644 contribute/02-post.png delete mode 100644 contribute/03-fork.png delete mode 100644 contribute/04-submit.png delete mode 100644 contribute/05-review.png diff --git a/contribute/01-post.png b/contribute/01-post.png deleted file mode 100644 index cef3dcaa46d8d4206f3b601ff7157c127d7eb55a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 172693 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 V{he5NlyEMeCkpEFC9+1o{{!U6U)2Br diff --git a/contribute/02-post.png b/contribute/02-post.png deleted file mode 100644 index 533ac99538d153d433129e59513a708d02fcc429..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 114529 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

f?AQ{Dupipdlg;C}}=T zf7!4p{qA8mKDqi;|Mu*W6=iUb#v87cR!bt5GGb}SAz+DCGlD6pc)NxaP0V$Vv4i>a zm$gnk1`0tKX_UmIgwb+3Ki7k6n?cXKJhFVwy63>*^S;-W!yMV~P30TN{!_22-_)xv zr5`@gq7^rP-2~nDVDus~jaqXGS4XoSWtQA0byD`r24UNcRYXR6i$eo!Rzh_4^yX_kGEu z;m&Sc!YpvHhU+d-+kuYY^W^1`-x~0!B?s9zWuW=eavY-H)r-qf`ITVZQEG~=Km0iC z6W*czLLD2YBBP@*Zu#h#VvnT9{&qmAywyP%$%;mc5gxUxwHPe_g~YDM z;6o_2^+pQ;LDiaq-dy0ESj<1&HNDifmtpSF+xsk2J^cw}|EOD7xw~54|30j7-S|E) zOE8Sxh?=ZEzwML;2%5s@T}U^+_Nr*jRP<+y;u}QFfxeU&>pi4@hN3w1Ed?zd90)VA z<%pj(mE0Lnv=9)H#R8W$>i9KXQ-O{hMjXB*H?ZQ@4bGz*I}}uOKtppaCbo;JnZf=lt@#oZ;i77Y%8;t-?>1UP)>yT5bq`R;%7%w9@xP$m=PY}%*h+wTL>5A?3~@O<|2U_;Nx^25Z_>Dy94 z+41rv33At|%tp%PHd#}Ok0=_R!{#@oKVL4RzP80Sw^bUpVj7A7eg_usgwIV5#FrI* zv$tHv64|N+$bjOJ0`yt{9?=-Of{Fnr$I>cuNWb|#)|H?J zGSw?<=1V%{jI0matui=GafpgFzOUr~;(DDDSZm6VNb=SV%#o-#v0(Q1oS*H$G}=00 zQk_83Gi5qo7kmgEjm$gnq`m3M-@HM5jfTiMo*6c!#&YrNmir1jhX42EWnYeZPQm0k9$v(EG=3UK&v7;@Ti1ZKHu4Hw%=4vpf+cQ1hP-`h!y^PE`-ZSmUc&HR$VV%<-4Zo#cl2I~ zM2fmN)qe1eLf5s>#Sk-6!FV#kV{zbRy2+74Fc$lQNXHd$V92ms6{3^zt7_FgqTNzf zstR9ngM=l)X!LztMXf@l`hKeY)BUrQ^#_S)^+KBzTouiU&FOyh$vA4n1=y&yZ|5_O z&u(EARo6T(Od$_2pfi1lS;@E_Jx8c$uOR>^E^o#C9&&-DAylpd&o-4W-)W(9Lp)b1 zmVaWBiYy3`ca_nm+hDUbqSjhF-dqhD1GwFBCw+2LRS7jZD!BQ5onZEXsauM>+X)b{ zEL4KBpunwn=oyN^z4STn|E%B1U}~j+{NSn8N(K4yxnl6m&1c(y2`?5_b;_`TS6!OU zL8lE_)3UO1$XU&XXrt#U+i5uoPV8d4zjpY&Zm@hFb40a%B!_0BjJ6vu)o8HNK`-l) zsV=5Ff$+=}KMz99$tPM(V10gdBz?2c`Dim&cx%6wHZ<=pq$ZpzPn9tGWh`EP%z@RBJU25b4R?!}U z$R2sEVKU0)%*k=~ftHacfao8sKTgmdCoXZ@lNRDST($yBn6|X%3vwiGT$%E({t*2i zPYNXj1YTnB6g<~?1aVzQxD$2D_w&Q7rC}Gsz1mLD5#;HnT|n}Q50S2u{@(?4_;JVk z6w-@PZV$plOHQbP|F380cy&l~ed#HQw;lm>@t|9vLaaR=NJ0ZAd)|D6SlS9B74V_f zrP$`&vX~(5Vl1y?T&UR&i{N93SY?7b8=c!*nc#IwgyYul#$Ksgs3aGVejL&GQ{sOczR@#C;2TYEK~M|m~4%dI%O{UFDhOcX7O~s-XHd8q^aKZCAr(w_@x>8WgIUik*x-?dSB89yhfZ>& zROUpgM#|@0iFAKrNF}$}xnd>$hc*OG9c_e9E%dCuwOppz3(r6>mfzclJ#luLVqStm z|Lc@eTv{T^2NRoMUh=oo-IK_dReBfK2hqUL+SICK8Mii0U7G2)+XogtT_6W3Iorr~ zw2SQnoaF5x&s8$*T%p`L31L36iDqj$1s)FWA-Av)fXGB|J#SaS1t52@hOPB*WwKu7 zu?0PC4fV+Punj$L<|OPVPPv`Lqc;!yAWgWdK)pxVIe1AyWqb>>I zVIQ3uC@(fV-?BhcbPreErf9Wq#oVtB?h3!uka;;FrD+H`$V2K zo9v%Q7lK(u#T`>X0^#L$Xcutgzi4h|&O$|@tYX71RYSg=HmNk) z^Gmz``^}a>fWRZums7{VgE$~XhfXX_m;Kf1l3%q1 zyrYeTza<=rCIxde8@DDXa5V_6bYL*f-5rQ#r-3)B4R0%AmXGMRCY<4?+t zqnMUx0OPC!%7eonq|G(&HIFwaBs`f-;m2FGoU6w3+}gPXQDLgKAdsoCDvM2S5Fy|I zkH830&eFu2feynG7}!e2;ZJZ^b~5CSA%t zJU>s$Sxkf{BPxx;35La{u5>shX`I}@L^nA=X8OqU@w2S`Wr8P5vJcouMU__O7mSdC zY`LjElHQT*Qq7r+b+<}s3oo0U$xBT{@r6&=dxb}R!Wk;x?erM)#L` z>oF*vMW-q(`({THyN1{@*h*gzkzYh(EF5x+j6i^OWh+m&Vw$?E#g+q$IHhVj*1w+( zifZe*jHPkld5|^Ooxe%JXB*I1N6d^`e&12V-{lsfWTTV8C-B(+$-NXq z5z`j(xR!Zl)3w9Ea7=!9DJRqqI$z?Qdw)*4p23K@JO?M4QEvRaTJ1?{Br8SDll%=i zHBXPPku8}&dygFA%VsqM<=FOj!bqqnixUb*ls`Tx6MVX17X%GHXTqHsbuvQAg*M&1 zB|XRZ6&!>K@N6<;&QYd}S>Vo!3YJ0uq;C7N>~K9&wo>gddCRM}YeOdtf#>D9gro$N zF|S%*Cd0-zAu%6Xk*i;S&`&(;t|qKM0qp`N%Z7RWM&+Z}O2H(L(3+{CR~mJB0YX?F zGA1DM>MIZ%^@t%6f|w9cCcsFccT~ioNW0Q9YAE6?FxkBs5Wk<4RitZDc6Ebg2HeDT z9M5$Vf!B6!F5Nr@n@t7zh^#^%EQt4IMKzV7S0+f@%l`T;xFeb+I>2J6AO!IHpc78E z7iFtL4&F}@ERT96m|9UJfFS-N2vKi6RiWv}?D7O$_Q7p5GVNF0HFk*5!doI9Mmmrk zRTk{)fgU103`Fie%&B&~0kESWWV*_}g#Fx)8$96~s<=2MLoJyGL7jzbZgGnpkCUcrlsfVlgvI zmM*#P6u=iOENeGvFBFt z`7dESnzOD4m(|NOe?AwOZsisPw9$0{^*LD6obGny(vaK{il^3AGdMk}r5{!7t!v9j zPId;-{&D}eld%5)I=fI>4xNYcdml20ounl5^QD=3Umgw?4Ga9L&B+T%FY`KzDrnM} z8r~$p{SYv+8hQfrV%tAqZ~z|fg2vxjQMt&O*xiSv(E#r*3Uv))PR#n5s;25s9CD{u zq*kv)T<(^K;=)v?4omK#bxsDpBEICElBRRol&A2!;pVE{Kive{)x=1((Igt=_W-mU z9eYb`G7CG|^_{VY&w667Bcw_gC9%*|#V0AOG6x0RJ{1Qa=tLD{8ina?B*j>2-r`S6 z!PrEgUn)(`>BuiLtAuhd_o!1m26OD$h{xW33aZHFKaqrLirs=RzYd6D@`SDU!nuUj zA{1OvK3nqA>V#;)BdzvEli3EX*mNdZo&;8qK|mQB_rQxj+yMPriCs;ROQD9momoQ0Y$LXOM<~)M zR=ELlG26G>$|Py)T%25|Hj4-ZGgQ>!L+GF*l*(SRZ1y{$< z(|t$PP*-Wdf{uLJu$|KPeSXXcLzneu4_@Y=jzEXqR?h!|y%X_R!VX8& z>KYn6*GTteNv-K1@!0Uih}-M3Z*sBLafEN#ZvK^L&F}Q(Eax1n_3a0T?aC{yH*x4qTa^HP+uvYTELIh?$Czgxl|FZF=fo>|zo z0{YB%pPwDw0*}g1Oj&RaQ-7ndyRvdhNVvPVN5rSN9RL=10In>bpaw87zDdD5%8K}1 z)6e9VEFlo!2(=GxMZG@%uzq&?Le`t3K>p7+Sk`VKz<#*nPtYX?SJ|H1s}gH3ZwQMC zbg16DiVkoz%uVHP<*-$kkgmM{>G0!&gQe-O^7R<-7{FqSb<7nFI#ITt9i;!t*Yh6zn-+n;|AsBH%VJo|V=?LI<_`0+rzF%` zvTQ}9?QQP>O^2Y5zOka{`0sST3Z}YLevr4sW1(?nlktF~N!^?^pO0bCGbR)I>R2;J zYD&E#fe^|+7NOAynTzaoJfM*WU4f9WL5ahRY(Q*SNxTq{GRvXW$D?Nlc+Y#b&_P^E z@5Z?9@ABM*sfGTm6V5fo1kd&pulbwlDpb?HbM5+PDqeY(yaCO)_D?cujzR&@lrM_( z+$55Li%I=UmORhOyT>l`+#Q47?WhWtWH5PHnJah|BtF|kL^a`PX1`eZHI0OSNBcNr z%IKRaO2~l=&8L9*AG~ITrdCXKvTanLj7OfXUf)C9{|+bVU7ueLzxLq6^(8Zuyt5B( zU8$<2!Ao1*DX^USfC*sQ)o>9BnCsr-Sr3WZ^`YSA+3!kodC_z^cziw*wRw)iyHlGc zGr*JxF1Q-?K$zQzuN$_I|3?OBIx+G2JC-0blgjnobsjR!&~NMXLm z|2eef2RM#kjC?ZzxB>B7zfbGsj2Y6{RTO~Gfwa=;fk~>~U-3+W4`kEFBzf!OK5i{B zmFAZOFqKpN;6L~_^7_ka-oEwN#gIdd`9-X-O~lt%vXc@AK3lzc{f^tI{3Tw|2BNzdAA<_oqR|iHqwmwK+4Ba~Xx^pxAq^Dg)GVgI*5dbITd4b8plo`#iz~ z964%s6?G#z1l?2I>_jiM9(DV0{^X0D6Y71~MKgbWEZyPYy*s?M2k01ocDbRSfdf`q=~&HRmvfF=GCVOIdZEwk zvUh`6@yZ&%Pn3@W*UDIXZ5ZSv+eZR3M;DQtXTB+@28_}H4y$nymo@4Mjgud*m=mcsjiUl}Gs}-^8TI&o zL29R?&IcFNskOC7F6TRx<()CvV4bz@&F3g29zqb>h$^mjjL&j^#*)Y`xc__31FqHR zD=d@V{w$$tBzrT;tbX+spMwZU_7OMRAD*wId9bNimuEIHL@VWxseZ4R4<_;Qb$V@W zEzfWEE|`wOZfC9f(w72`8B{qN8N@8_Hk^;eAZyHHw-3^nXO_v7q<|vK3*yr#mm|bB zdk#A8#1i)neT||nM`j0AwNw@J&E8QGW=gDxon6YBM7yV!=IrCDVuHPyj*1iA+I!O&#<*i z*7_vzVr%8(n5cu-=Uj{Q+T+&Jr5Vc98&iROVOgwhC`abCgSSdhKWvfM zC-}-yaXGn(2o~q)0mcqidpEhK{F1gIz+GCGX@g6TOYr;N#h4?|&dK>5dN8^Adn&AU zHD__(2%8|YH{Ced{TqK%3%_{V!4CE12kcL*!m3Ak$t>q5oS_?oQ-7Dh0U5t5e?#F+ zO=-Ps>uzAb7@XN#Hz2TV}d+8s1)VxrJ?&#s6K?E>T)m}T2h-AUAd?7Df<3B=#7%y zmUIpQN?b!cjDttjIVd-v?iIz#U%NkWN3dAkq>Ck9&J_bvhc{#3vSsa9YyRA%w@53p zSaRc`mB6u8-mT*#e8rTiyWRM$LDVSkPzCUCqbhmyB5n=N%uQ0in#C?h3ure|vFv}b z7y^MRY#L+0V4DMTD!Hwj*`{1$SRY9uiz-pF@{#q%(!_ky<^c{UhLPlOYzAdfjMEr$#l1#}Jm8eHlK`yY_=3I2O zQPVEBGIn7>`1S4aYKO*7dy10t#P<&{F1i`zIh=3w0XmmPm48nNX{BTh`xDvh?fBh| znv88Nf|0Bm4kAEhZ*J`1X4tm)h?G76U~AP1<1Fbbbb2q?77hNWEip5?>i{-AhYf1b z0`zya=%|3(`Qy?S#WR%}4LrzD+qoqKZnL=pXwDSIW@JxFr+9>Yq~J2g*40x45~%YK zAA;NA%9B96T5;YCW=dxB8<<4?qM%UtQ;O3pk`IdWu6xIt-&jW1i2BZ#*qu^3p>z9A zB3MZIefqt&X}KfqTg^H6F*T!i?HFUrduZp*;h5Ls=yz^T(94p`F);>$cP#h^<4xv+ zzv|E!(#*!bt&i55h=9uYbd{oALfvPYDhZXkuG-&0|K8#OY^1@TNPrN!ch z);5b(*TFd|umxhEUcY6tl(53Z{C~SG&t;Cp_3Q$)c1!h&xksl4N6je5_9-45lSe-v zf0eC>XH&D|-cgklK^4>1KMn)-N^%reYG>K$T^{%qM~3PLj)935QNMOn!ZLT{iL*}C zEq&%o4e7BU$c)eS_?gGJj4+H1Q`|oBiO}1OSI}Z=} zJRCVXa*~*c#kaXeWo^fmw8~`Okr?08EXurWo~n(%q4?^&=+NwHpIoFZl@D&XpGfEt z%3D?UKgC1$m8ceAJB+O$=PHT+tOqmz*Kgt0TRtIbdJ}ssl2djeoBWpStEoFtr2@xG zLu5W3s7ZH61E%ELOrWOj_ZOnF0zya;Q#od_Ncvv4H~cNeERveJA3%H1smxMDY@t2y zcwuoN+2G^#ajeV6$l2%v|JrdOnlnVWOX_s?U*PTBn+;>2!B;10Z)z<)ppavTV;HeU zwaiZxvj{9L3cGG%<2ffu7|mkZTT`l^Yuz+jMVEZ$M?Ai#X1j`HUi&wJewrg`{1SDWu^apCKAYuiI za=}S#3jGf&b#Bs4C!6;*gYtaY0L&46V;p{dU4IeRoGFVP@TP<5 zQz~njQZ#$XcRMZt>*EwAmO}+aLExp_%1;`>l+Ch5XSim{Dtlqa(uK_{p0C5&&;195 zwPo7l7bEV08Md0(Bw&~GCGVZA8vC>%+QzMcd1AdI-Q(k-qiXekMX%Sk{Lb_Zzc^dJ z9V754<%Vk{nzWek@rsX*C;V3+9^g3Q2;&kw^;~40-i4o7$5CTwj#5nA`y8 z*sI~Q4e+Zlhb{n(16FO5#SXjXLB$u5RAzfjL#)9@^Ba$NF_C`;G&@Me@8HsbQBFpQ zO!6-y6bZXjzh+2EEh?Y+o_Xtd(F(S5aM<6N#Y7|~lSh-J0N>g(hL!eJ;?Kv#7hL_Q zauwyJKAo&zx=l6J^&jj_0WYq*n+)1JZ8{N_H|Lp@w{NmPndg*#o=9(W*&cgR!W;n0 zgMXF)Q$(=Z1s9)*G=ZbvC|dK=f_Z&sd2Sj43X_}Ge2}xRa_C;p&HcPgJmj{YvsnJy zc&}O+*dx{MIGqJMTW}-8@TXBQPt;hklxbI)hQN)lXY|KpQaAK};uYYYR!JT^aitWFz}=&st>U~iE?zw#d`)2WK*1Ww4AJD}U61MO z@bT+yo8{EjH}Ns4>o8jzp`g0dECDICFD|K8_jS1bR~8`Xw58p9lX(np;WKh=L`S;Q z$_pcTq&c$tB?W-1B0zys@6JHa){EILs$`5`FsVP0r9roPu8xe4VSf0ZBye^OISK>;U+C1=X z`mU1~Gb9#79jSP8+YKJVX#l(-dxR7& z{222FMn4}2uf^0vRQP&VUWsshjl!PZt3u#nKf=S>+7jCDqh5p z163)Yf%5;(EARx9pV zz^WZafc-+;QcoDlw~QO9CnW%xSDd*CJIr(Hg`Q~5_G>=IFx6amt?v^2iG-P(ulQ)d zbWc9cr8L0$RSa0OW~3S6f6-JoQAh#m`9dF<>J%i+#LdSmA?mWl@Yvz%^zgpa-d8u{ z)K*#bH%xV<1l;ff%syp;L_6bPOQ?$5W@R*W)xm-lUwI!#SdKO1fi=ujSovfhVt3Mb z8%)H|K2zQ4pEF~t9lWh-fjeRiUW`!~@zR8_C)`(dV3c^GeKwj{)N_@h1u#qp$F3S5 zliQVo7j)mw1Y~_g`V5N5=GV@Nbipr27o~a^1E_5--Jb9>J?O~wn`S3_sH)Qe*rlIz zYPt@@Y}YjuyQ2Y&_-{DxAmH+N2~X3U3W|UqV>MsA>b=-0ZlHn&+}n9$KoZkN=Y0S^ zcQY(~6_P8b@cU6%>KbkCQ{YVtMKCyDh>ElNDJDN=k26>DX8UL;sp09AX}siw$JC9a z_p-0n{O0l$uHz?p3JL}yMR@C*6~ z@7ZT#gEreP+Eo2#eyIVE_h6I%cC6=?r&P``=A}-r3l>6d;27 zJa99G+U2p{xrBK2m9JBFc;4FkHG9#*wTUy(#wq*^B=eo#<#}`G>VePkB)Y05Jfiu5 zM8Y>UlBMZw&g4Kw;GYpIuVq|*y@aM9U#ma$AgX=iT2xM0#6nd_H4c`%f?0D$7@FYWDYVQs*5!wb{&4 zDYcHc8vtG3BDX4h_4j(JOWGi}gXxbm>$KBRCfHFG{BGoIw@okp&IVoQkCVOi$l!`dDdwGKlj+S-#+nK;E$c|W(5$@HmLO}j8R7rZ|qgL z4tl&`W!sQ%n&#B>)$P*OLxYp>1k;Z!dXvnHeuFF6w0;a9JA1A7Foe;({(~~& zy5K%RD^VhPlreOL16TE3*OF=Ing&77k>;E3WSxR0a_W!ABoWso_uSA5nleHEUimHQ zq&&MjQH*9!EqMiNU+_jKPS)WDx98*EGwi?S0$g(n1$-M#yAl$A zpX(euE*eQq0;Yhq-XV|u4+jI$4Z#37^AzDqV#ihE#qKg51aB{HEdDLoTR-B8hFz{{1EKSI*P13TgxUHzo~k zzny(v=LEWLBbIO#bJ3A&&~8cUo0xmrk`kwMxq-sd+gB+{8R*DB+mQRU2Mhh$kQKR| zu6iG-eQ9o9leX@{t)Zg|Ppu%{e>F9gYZ)$Pk3A2w98ZHhDE6yR}g6lZIFtyJ~PpUZi@QE=1!#_BM7p6;noB)5CWDfN<{H$Lld%6(X z1o3heKy$JE4IgsZECB+caQ|+;6%oM`S+u_=H!fobC;JMABE;G23l5qWszr_l&7I;U zCuQ*K)NF<0KP381rZ1P~n?7n*w%oOJ>euAZ0wmCt%NX94+DTbz+AVh z$GY#}2}5qMGj(L2s?&EnB!+C{5g@46{|Blsj(Dp<{@^9Ng7;L;9>Ds%n1uM1(8=D} z?(O56u>`E6J;1NLd9=}TCciYm8{h)&{_l)=AI&j0u!Ns4~ z{1`V%z_uq$1z|a*9V9XSjHbxtIzNLTSpG%zFonUq9L&K0$wC#pvI}%KO8)eDroor8 zFH4t!J!O*4MY1M_yuQ?jKZ<$p{3-=x1-rN{4iMPR+4 zS=~J>-&(xB;6w}~5a)){dwc8}{qW3so)2(JPo}J!cjog?{-sI35#eC`ewJ=Q|63Nq z_-4G2hT+YAqN-L-PNI#*`UtA(zmymn_qR2{tUDY+vUi_*2*ZD+5!rajLL z-+^#Fg)X@L&R-Yd(}saW{OaVexqj#AzZ-I(ZD#661lffAYze_YasRyUr)L^o25?W0 zxK%CHqI((jjt-CVyTBJ}`vV)}L)IUi$oU}Vu;FL43$7J3yGR#KbFJJSv=9t5yeG2> z@cyc!seC-|x&q{?AK!Tu+UG zn^Rcm>?ZfNY>?01r9#90$3xgpZ<)Cm{!HHC0F|RI+f1xoIH`w;{(p4^b5Fx)iF-pH z@0-nEF#nJ8fEBLk;+1XbyS?aBr2g-+-zcavk&EZ#SthW)@I|F25^k6$QA4DW2!; z$YS6kDed3CKX2f?$`2Q%4*%BrUSwjCBWmitd8z`jZ%d(!auWY(tgZfCjaaqv_FH%! z=6rKaa*I^1#UHj|7TLlq z&%gH$PpHYK3l!p>I5T@S6c#rUl;uy;W!M1$Yk|pKVJC0ncT-YKoLF-ldn4!invzCu z{)!3Z@S(lq)qi&=$VFIACdTn5fj5)VzRV7$2A)(&g&b`?-j)$EVeT!+vTKLzoQO}gK_ho9N7epX#FHQ0x{dyPasJ?>C~FkB zCM@QI(%R`*321|Wjl$gvm{XA3~vE=a0Muyd*m zSwDqYR+&({fk>vwjGL{6LW{Cb=c|WfQ&KyV-=n#@Zo~Y09W81C@P^!3W`>;RkIoC} z@1NNk-Q&?ny1g_oFen6B1Fa8vHtd+(Kg~{?G!qB6>^Nt;A+OW*4BoMdWdEkId=4iD zH~?2_oM^lE6-HCAHPmc<6OSAyX4n(bql4IU@BZPg*8U`y_dvi`_Bs?7gqs;si2DW= z35Q}n$9*4}cm?$p-ebYTz*N286M?meZH*{UK z>1nHS#AE83z`--e`rdX7Cl~!`Sa}+%x(&^mX#o12*dC2u!%OTf$S7F_#aGQo$7e{$0?43yzrt`yb?eGt>>;=s6+-o3e*Y=SJh`RB{KjPJ3 zu~ox#D~V_xXLL__+HAWtJ1R@wj_k6&J^5A6rATe7r=8|Z@i^p}uyrRXWW&N@+6&eh zBu%Xi^NZ&BLBSs;m+bUK9E|}_!2&%$i2`lj^lyP8Uy&<*q{|D|aw6m?M{^PL`HbUC zn=cSRKBKwbP$=5pPtqb=7rR=jfPpfsPOfWj9B%#@5&Ia?rvi2796t$0^!zARo;gUhWL| zoxN;9#q_{2eFa{>7+mo$siH+x;v7-OiW0t}ZbGNEHj^b<*^ynVQQ+i4{$gGkKwTY= zkZOi#F;C#NdDm|hyJD>NuM>pX@Sabo>p10>-E#{xYp$O;RXQ^wH_yx7v*+OikY`(M z7b(bapM>`ZsM@HOOrjrYKSr!1FW*~w4Xws zfZi{2BBIz>u5$hw1vss2ivQ;#NhUhE}Kcg8P9{Snanyob;_f_$+&q#>;2GUc& zsIgjik`=qqHj(YrBAlKyIU}ux^*genk#cx)@(1N2KBAA4SvY(bB=To|F;i!`GTX?? z&AJ54=`yq2N9@Q_eL}rh$RGH`$Lzv_JNJ!T;uqyIhS*6*-1+Dwz@qoZ_3NNA zG%a5wa_JCUn$$Skr94qxIiRj325Ii6h}uTG-BC@yk1Tb9a|bV@a+H%A1iEoGJ~Mf3 zjXK-du*|ZzH#WwA-i2)?UCjq~@B~DP^)KpO-1okqDmuQ=2 zruK8@#|2xaOF`x217#8cnC2*3&q!(D&>wkfGBTN2mf62WUlza2$tVvCz%)cON*gHc zO+OJ`S2o)e0tm+j$lxU`PbzeCr+OO?S>Z2D1F|IwV0vYBejBSx(UFlX64PalS<4N0 z0JK4~l(|tcCTZHL34&kME()1tqD@3iwq751U&j<3IaJK3G>MBpNnyTSDH-etSAr&` zN!K%(i;E8F1~B}Pm<{?qAYy0=h$3Hkx1ywL6M3NdWpJ}-mWP%$MMqKp3%^Ec2O?wJ zy^)_AL!E$tivp@(fC+c6FJprK>iFg>{0XYoey8?)mIrIM$WklVKF;xxG3D_im~6W& z78B*~#mpmC`Qo@sY3m|HMB=v&0r#c@KHOvWjpCwVKd5>;IucQnUxq&IjEJ z5vOM5*!Wb`(^#MvvxMP}Imf@)hb0H-V{Sov{YLPa>rZO4D;LWRO0#{r zN;ex6M$7y#-2Ss{8h9EHX#wV}$<>uVqbpKVS0`gK2(fbHDBC7{2MOsYHyyL&u3)fyDHF(rNhE)Pe;&gH3ll5Iy+*ZpUtHS3Ba+ zoirgMM77(M2lL-lN%e?bSxry9rc}J>UX5ILsFCAF7m1)vZo;MJj*9cZr|mDp-ESpS zt9CE`BtP~Xw^q#5@FgP1#IAPhU3)1ZOktqZ6w`Y&H<5vm^vh8aJ=)W#x^Ww+%i{`c z>*B(W0=m-NU}6o~+c&v)g#_N!y|Q@$7=;jg$lSksS<)PY@T%tlrC#?{pw#(h;V)bd z0hiLt98vr<6S!|Yy@^FOfPH5a>9P|NMJFdOkTbdWQBC>@r+VW6*`A<9%znuG@XA;A ziZ|+CW%qhWpCvDZAT2kdX$W`R4^G?x?-fX8riVd+n>{;I1N%=vGNeAG6zGCDH|WGN zevdzKxu$zi=i^VF*4L(wD}zg|C}Wi60(5vpM0=qHh{ZG$ct zQ^;ZpmqHWQ5kz!;C||2RSm9TQhMMdJ&BBq}Z~+smOe-QOkerc)oHgTUZidYH`52xC zD4W>MRhI!qgIW=Wy6t-${gxRg``Q(rlDfNPm`597jtr>HuckeQPIa|n0)xLqgoraZ zRyhnlFTC41DkX$G^KRp#wh_qLd3?Fwe5Pyh25R+z1o|+8uDynq(t>+Gg_`Y++ORy7RYXLS&M1UHH;&w zSmFEj^APmKD0l^%hF@gkxP;5NgP6DK>(KPLNcQEK6Jjx~bTga%zBXt=7j=R3(wo6A za_>0aki`;-QhTI9m%Un7n4JswzDs~9^SWYkqzvVvva8&*f{GTz=N{x7>aI$GHR&Bt@~qa zbZ$u^PUz2i8j{cpZ0Evl)04M)%q?Bb^l5{x>NhrHrvfnx6;t!+0hHFl!11CH&!2{^ zjA@|+aT|T=8%S}U$I}zB(@h+^vSm>4`n|(ykRnsi{e6Yjce}pr-?^5DiuXYTZeH z!o(@MaEEFH4=7!R0DMHTxkv5XYj1kb(B*wBr{v@^WcV2LVgs>Wb6&dffL-XT;V}m% za-B;M-8nvThEPIi9kZd!yiyT)8-B8ccW~}Mrb1^unTe)7g*7t=sL^KrK=_MXUdR4Q z#k1{j+Mz^t%kytiU!09Y@&eDiNy&(YmLaq~AK)S#_y0D`P7X}_bv96hk)%c2#jNyw z&DE_`Pp-!}IN$O_5-33~i8f-|>4J&7TVZ3Xx2zNL-MyKgyJKsDE}=y@Td-2PA%gdU zJ61;ha3app0lY^9`YFrAluKJYq5SJ30IwW+4!OPDNy0p0@a$}GvAP>$)eKhq~uP&9?o-pY}aWyDWT>oseBDxT)aC^TJLham&%Z$v>6FH+@y^J!oP@H|69hfwH z*we&)q}8Y6#GZFMxwR)zx$+4_SUq%^fF1nUKlPi%Qo^|nhD$o@X55Vkd{T>ejFYo| zjH0x}%5SZv`FDSoSS#}H&1f4MI$r&6i*=gSONgnZ1LQ@vTRu&V@=$2A$v{H0bUgjT z_MKQXZ?G`T;UdcP{x#7#_jUzEc6gC@llDPn(o2s$vf28jd-tDzz6@SbO{5iaW{EmN z&NeCrY86562uBelxHc~w{ zv&Wa({;vG$sROF5e7A9Rme6wgOAc{u{aGu01r%k&4Ox23dEy_}3YUE;@}?6V_-ILd z8fYmP?03vR3~(3_>(OKSdjABvDO2x$({Np$^-{NRUi1aa5FZcf-eAnkQT2 znTv^dlI3etx~7w!v@?UyWDrMxj$$g~0Bus~Lp_@9Z<_j=-1r~kMSu0pR0lWt|Famk zdw$V#qqKQS$H95%Is!KBy@=8ffv#IymTt{f@D8lP9O4NpC^{2Gn@P8VyMWvu3E1UK zl?x6k`5<>~yVQ-ur?+J1Cj;#!tyoKDsyO}j+t9)3&0|@!(;5Snm3u4j4 z0jygn*ovUQM>2b(iW{ZBagabahNbYIK?UYhtwdp znlhxqk`?$a;_s7EWO33wiam_sRrWe{Z@1R)OQo zX`9=4lV%xp-#2PV^Q6x#%myulT*2MmV-iw#eNw1%e^HCu0qxb%sh(dWQQPGe)$iOC zbKKTx#_sODvY+SGB0sQQE|yAvD(Y zam|ry}>Z>W6C2SM>s)&Jm&9h;?+l z^L{Lf?S*dM0pVa2c35!pYimoaZFr$d%u+1H`g(LSA#Z;|DX8aN5K8aMmv0U{xuMC^ z-+%zgz^@)&lDSgBT!hr~i4bf7J}Xz^E>AlKj*3imW6>`Q+g+l-O;d^l2u^bB_X%TA zlF|L+Iz}O%oOhU2#n0qaG)r6B^f>CN*Ac`4862B#r5RW^=+vZLa!bS8YP+!g?c>5H zvd8&nZvXbD*21eWkceJ!OTMB!8voIr7)X4tEaBJ?x{HgsW~p?9mm8t;4#$Z$No)@Z ziO)d}LAu}O%j!MQHl8~RCjKx4Y?>V#SD$&Y7yI>e?;OSqFCU9~ImqMm*`yC%nOl#v(b{v&;Kh|vf9&u63( zAGy^h*r=X(+FDl@hi>10l}P+LJ!Ah%XkP$UY0F@*a#>d(R3!zJFbkh`h34(6eMY(` zE&NWlc5S+ZjsJ|?EAdv#;-jK;ESpg8=;AQWE+q9>_--ReKURz{9?m&=KXKTWQWIfV zgC3PI&`{Q&T^~8y@*wNK_*_rX%_;Hf>W_b8CT!gwLPpJ(zV7fhZyGK9Mj89<%lBw+ z!^xG{7}8&%y}%yw#D8t++TQ{kIqU>VHwK>`XO+$;Ta7j069x}0K-ZQffi{!lr@5UT zwoTACGRsoEBI#{^8RIJ|hCtlZT55GBn)LJYW2tX^HfK1jsi9JDvR|+;XTEla;onHI z-m?wLE*<1De@ShpNZwbgU1^GO8cT8F+Wl!x!q0^=oOk(Yt=GtP`~>6+YsDRf6r>n)`7GvA6@rQAVjw(pnvZL%kboD@cJUK|z}+HZ0&vL5JGF5xr6LgpT^*;J3+m&e zYIo$e&2@-bFn!8-+eU_F_i3$mfE)D_cOYg!J2Sm?0OhYr=K&ASQTq!GaHW>q#;ID~ zJ2e&a&XvCc3Qsf%778@RggjJKMW{jWPYxr9CSFcBuM%E~R~FB^N?D{NRmSO`=l_eV zYYwcVYx<3CH@2N7H@4Nrwr!)a?IvlQG`Kgm&BjLK2Dh>O<$2%d)%Wl2p0l&Rojo%< zGiQF}k%ffe3Jk6_OsL7{h_|vAL7V!^p;!^aAqL1DJP6?((1&7N=4xE8ZB>v9@8l+y z!mUmsbjcLv)f9(nj!Q}v^pqYAql=bm;nhpLz^XLSboS56xB!$|^ z+PkwPTsY_;@HjX`Mo*7Xe-QU&PpN1~%?6j(Pw)P?sCnaZmyT5aAt2NLdRgg`FSn7J z-PphIkd{`w40C>(etb_FY$oEwh(JoZ><7tDw{@-_wlCgA5Jx2~R8_{G6hQ#seTYyu zCI)y*98qScevQSuIobS2j?r#0x`^~h=5Prgyb*`03ZJQvR zYLnsrEF9z+9{xG~aRpTjGm{?Dq)zcul3#rR5H%WxE-liQ>zVpA}^3z)vS)5)&fp2B7-si zwr&qT|HC;|K+Z(a4@;GDNM$lHK(MUR8|BSFee>jknax)-Mt(G30h#{cBS4fkGN6b- zhBs4Xew?aen$1VCqC?HYA(vPZGgggQ2C(+6;$mC3dMnPHkj>{=i{%10EMQce&D*L} zQYfpcU@{l4UiBr*nSm8^j*Xxm*UrnnRp!T~3&$6{JvD!2ge1LOm!nU92uW##OnuZZ zJ!P$^U=6?6&Jw?J$|p4kY+}hj&dO3`I)q^K91g^HGE%1J72#zf4Kh@gF`rm-w>KSs`@@kx&g5(>j)i8{2usg1DA-Fd5M>nm`Q+!a5jQX=y{=(YmuG)m zrmJ~h?yYfF?iEXFz<55NZK16AF7sbxY5EvWoCP4-N1>s%ByhGj?TgEjMdChi2TpMy z4DWj{ZAc?s>qH%>oUYJ4EL}_}&dtaB$B5mDqp&wdo*ME%r)FOKZK;&b37|iFYG`ZA zN}<^Cu-!cFe3#AU1CW$MoUkirTD&r1Ld~;*XX{G2OX{tb6XQ!aT!Qc;?5Wodh62$9 z923H~y#w6_n6$CJQOHYeimvY*3VKbRjNiTfxUaw77iF5IycK&fGT2>Kn0zNq_Czf! zJ!AMhAPUqdFH0UJMrYhi*>8cRm6Kkqq(s=SN1llbWqz$=B;rx^{jY-j$HI*-$l1puG z;FC*&CY6l$!@$IsT!IEM^}b>rnF1BI_Ly8WshNMnNH);u0=zNTJc{i&$kCb8y!J_z z$;?l2TCVrBsaWgyLa<=kyM|VqdEAT1zG!}G%$SqF4R&T}V8_!+f7xoCNQu>wJIt-Fb7 zBsJj}FD_?6{WL(LvXH;Jtqsu($3-3bHD%=l9=^A5ZnC#$8GX#f9AUCALhGRZ3Vkpt z$cDSKhJ~Zv!xEqbxH74XuTX=#7Z)tHh(6ao8M=m6n2#~<*++h%r`MYW z1$~Wz$@@HUfd1Ip02q^28~}!yjQp(LftO(Om$P-+>~?j+iP%skAgyeRNx9K}`>E8C zV!DklBRE6UXq8F`JvWXB!;u6`6PklDSCr9+ZF=(Y9%*`N0EO7?E5n@L*W{W3grgU) zlVJ%)6Pp@NH7T?;^b#yIbeJx%)dS@q?ue-t>=-7p6GP=o2R$n+1B^et@9d9W;b^G) z)crRhn-O^rzr!Y+cDStH{XEKYsR5HRH>$gJP6>W826>^I1g~tAWDuI1>Nr1(04?oZkOdWlA=x?e5HH z;QQjLK>R5uYMeigrly0ofFjpZ8PquTc z=2AhFErR5%3(QjR6CUhtaNVlY(^HWTH`rBCNjmI~2nfj@A$`XFF7|QB|Akk>o>7yP zRG+VqF2zqvQ`;~tPrs`?79eRenY zBndvP16nTB)Awjsqn&g3XA5_TrVOr%l3OZPyo?lIYj5^=Qp~W=V;BAeLD5XQOLb^3 zL6+0*TidKIpVgMWOjRVy>75^-Xr<{+ai3{jHM{=$J@PkY;ksP`TF_Q!cas3xO@oA+ z5Au0|ern!0xyU$2p{tuS^Gr0KVdHP}%bJUp+q#vO{UO7xM_ZP?SYO&jzb@=b`KR3i zLW@fCuT`zfi~Y)razyOLs15>ex=P$_IKu6ZkjVK9m5oVe+eJJzr9N!03VGrPNRyqI zjE*mc&$k6OIb5EI$K$PkW;bznmlA{`$)80;^?f<~PwURlv8If-uV-@nb3@cC4>Ryd z!_d;Z`l)l16Ngs1yjQYpa_3<!30Nr(6bu*niNEmOS${3`lJkp`{yrR>96FKbB_9 zxCvv^H+1F{u(0`P87CYYYpT?fSPWmK+l77R8n9rB#17_`77{PkO;v=AIgIJY#Nyq}N1Y{Fi#K2z5=28kCYZ4Y90mWeTN5RaQy&~Sfo=xXHwhvXOCfv)w* zIP+noDfXy0(j`Zx)O=kY_HT>YJS}go`P2fw(AWAVG6$-M2WmZ=IIQo5JIa89k&HIHoa!|KDaVu~9OtSO!Q70Y%fv(L7W zX3X`>$)PK|AF=uCGYWIn3^b9V&- zKA51uCz#h;J^0cDlE|GLeXW}ljpRlnzZNqD|LCdV#GoSQ7e&h*&F1x>N?rmxGTIM7 z{Re_3b6jIH7sw}K@IGE#Jxkli?k=#BfL>C<%5FqHl_kG{*Xw4>!xGvBC0YU1TZfW* z7+?O;oS=!ie6Ysvey|9mMSxhkf2)w|hc$0;4IGv%jD&|A^S70FAmGd~+X*}Ya3&fw z&D-0J%_`4StUK6T|C$2J=X5f@=KS>KI>X+ouS}OAaWY$M^tXuuA%1v~^x#&7BL4& zVPGK`mA~(NX4EUdml{`~6(WH+B~nZTJrX^k2lPZ+y^1cWj3$<4{#W zNHs_Zh^1#`c4*fHQv8TZN{XU7Z(IXX;a9(Y>T=&i?=$hblc}hv%qtjr8_~(fazclw zs3wZ^Elrk7i%TbzQBwv%v&#eZR~*kJo~H&aDXF>DPrcH&1Cv8n+@?^`qEKo4gMx+S)Igi0)>||!`0>*|D zJ~&A|-^;4b7^ug_PS|nri#hFN9qbO69`r@L`hLmzkd96mwbx)QqqN5Wi7|uEV~x0K zE4O~xOJpI4MoY|tCPcNHlryuLP+#~d{BkRK`|di95uMG98^m`efo=Zhom7UL77%w( zr+H9$Bep+oViKlgB2+#)>K3sDdElq@2or9+K3|k5qS-w$p^)nQ5OfqX*_%Z>_OYG_ z6DNyoOkrCNf@|zVR#}=Ik4HF(^IZDwYOpEUVP!)ZQKpO(1Hdgry zX=4pj$RBy4Qbpn+f#ejrvykQDpv*y8n|+v-5u>$mnmCn8^gTzzxV_qX_OJdTG^*uY zMVEVMZ^LCy+yM7bC+D{yap{6UJ2Hj20(B@zUD-d$AyT(2%QM7?hI{YW5fe z=cGoSR{yrU@+%|uxAf;j)@)hLf}TXOXSeq-p)gmfP_0{gfqQy0cPn#w7p-n>M?yTB zD59as1L()(s5>AWPft!Ef1hLvG!-1s`-f3QqyzO*Dltw(wi5nV z0BD<0sLw=@INRtb?K=yI;FSo0*T#)2eEKZF)3~$ZpjH*r`C;8GbT)A0%7to>v-fXH z&POid$qfENLFiqR;c72-5f-y=MtKuP3O@ZsKhuS}*Gd(0IF41(ItK>@_%pO^^pLE9 z~OJYoWe{Mg*+wth;?&B8rN(?YgGFA%nT4{cxl3m%@|+t z;ii5}&uJrQ-%&6OXy5O=u`(rzX)NIe?LbM0J#)$k;%s;SxMOwy0*}F$Df*pR6pn*?r-VmyyMizv`iBUk(vD{5 z9ntsKHi(3EcjCU>KOt%~|xMdV1!5En>}=NhqbHKC$X5tP$e>(^bEaZ^>jFB{4xXM2JV~nf^_9CHoP~VHN147>DcYb zNZM|eepI*Ms!F3#5L)#_m%I(|fP(HhmuUB~(xzm2x_+H(4Gr~`+isK~UrLh3OkaJy z!Hd<6jH8WDTQpAvJdAxQyXutbANHh;H6LYzcxME?9c&cY7D;AGzw~OueBQ};X6vW6 zbn*Uy&VtiOs4RGkuk`dl`d|#NB==stEA3N`KsX%FK2FWb%K>HBDOoGHt_Y&hDaTeQ z6kZt9$H|N}i+#!HyTrumt!`-C_m65ntL|-$X&GYfR?Y4*|3vZxhHH7NPN2wvR{b?a zl`Fp#^Q|~WK2e}V*rpTnV1pz%LxCx^!!Nq4ccZ(q*PHg|{$oDs2;WG8;0?>E|K%5n z^GescsuUME3{UuySmDzNzFp&7A)@Z!v>5TzWFXB3AL*H^iletE*;xv1S?0AZ5)^MT zop)9up3Ka`gtI%tHSxUaWDQea@1{pc|Xyy@r`5`{bm*|d`>*euf)f@)Wg+q^I zsgxy^ekq7nmm3WldAYaJpTN#y;>JURi9G&b7200lD9RS^EB#Z`!^J>_x^!TrF`vi zCC+jKCsf@pP!+p?>n%}ip}ZtNf}3ILKnmVVpr*V5|7`1Tx~oFpu~=ELROurQz=$i>T($6BD}M2r9Iu09tT){>GjI6& zD|)Amj}*F#qpyn8TZ#EW^R z;e$YhvDV{DbXg>FdtgEs_JnSUf7)H+0&}{9nxVLH-o) zWcEVayvVe&4yd$Qmo&`3h9e53q`%6U*!(P@h$?|ehxd)|KA1)L)#k4*>*d!H>}g=~ zzWTNjgLLpa|BcC^AmpR-<`cHm?BDk1A8Wx^(H^pMD6;okpnYf?{eP#ndNAH$>|y7m z|M#{3j9LbKfJSzHfe_)*{`k)&<*#Y}Iz0N_A30YKX>7ERg*oBWCJ|#npufE1ugwcQ^%oOWwZQP zR7TRC%0PE{N7&3Y#6{LumEPklleKnL?2WNFeOdYk*2hQ zYG&}iq)xyO68FHVk*P#;xf;KC9aE@U)fPRrnIUy_VE{y%YrrROAg=1K7Z|ZTJYJ~g zjdv}_U437T{N!u9O;x*EOG%0+e9Qbx&rktE+EVpTf!Y0LdisZlOX{N9HWEY7&!Grg zmqf!2g^By0cTnXqi>h;9aSAQnQC%wa;6Mi=mjc0NC7XONeo5K-!M1O8ByaZ&Xv_mQ zMk8++YRszGeQaJ7X zr0h5lp*!Al=F%6Dcc|CY;hK{sHDW)UC-wO~J+q5Sz$g{JpOW2})_A{Efyq>EBk89= z*1d5`AeaB7C$AqplYkPO-(fr_cctRIKvsRbpLPy{!ifUl6RD88KyA(vpd4&wN zm8FjuIm(}NBl2v4JOt1;KR;j=`Cu-!8*Ic$#>~}Lu1j*r?;HzN@0(X1+ax%hVL?PL zGzIybddK+~pbP%Yy>?3l6|q{W^HnSDTfDm1p&biQ@;$0bXD{z}+%+1=mNB2I;1QcG zCC@xw6F6)fxGCJZ%uiH%05?8|;x#RiGcdu6b`<{cKD@TD{nvK{5z&%VeM#HXDu$c!=}v{s3pgSk;p3!>EKv zjjJLHR_?r{6%D_aY!#nx*eu`dY=(@v(si0j^+Jw95pxcJN&izm%!_5p z?&^h|_E4vn9yUYo-EuYC_Tv7^@QWd4PB}6c-_~Cnl`)fW&(N8;gy9Sk zDF^?xy8`~oc^tiO(t7=-!KL}7?FKalMMS0>RZxtRn$>);Bo)k@PlqlHagMB`j7U4TAU)-VUs^!o%Z(9jc=63Qhq4rB}Nvb!!=$Y=&7*-295WNEW8CYhAR%#uB#|8Bi>?_0fj#d;#`&)K-Ks zO2bbLy;Rl0OC@r4L2om(x(V0RH$ad@XI|{Qp9S}K z-OQp0PD%Y4*8Ko1-7;B>?{Y^ zUBuZ9VveJGk;E4&>)vAJ)XOB+{aP&pKl3|8WQ;37Js5B5V>FTlRnPWZcwDwijgvJ! zZi%Gvg*qjMG^B2(Y8W*?xW>teYX}jdqI%den}O|}>h3k)NZ_T{fQk8{*Oy1C@GaBm z*-{(z^w-J3~sF+Lef3P2Tm>&}8^SA`y&jOM{46CYo zPb^UeAd^|^xXfGK6B8E`e{8-b0KEX+1e9VgTNKWd=%p{-7(!hxT=9fBamUd%0+-eH zEtUyJ;-y1x=d{L;b@+_*oGFWE8Nb$o7`w`8$oF}-RVe0i5}w}we)*M1iVLaBYZg7o zb?tw8y@cep_?fHoSi{yilslbM=XY*USj_%TUMEo#&i~~5^O$MEhqIc}5MyUlH9URy z;f(-E+Mn|DO_@gHK53e7HEA>h?;J*?O=08M#n1N!UqKFK@Rz=K%Vmk1-(&{a{2W|K zBX-fwOD!-RBcONWBXI;>DONJ0dnz7XtpMJB#?Eg%kDUdV(xm+82_GO`U-u+w{8i~K z<)k~{&4LX{V7{9pK}@z+&w%lzn#A^I)jnAHm9ZqSDkzor&=$Mm>yH2} zP0DjKck-Siy(X(neS~y>9-v)^7vrQmAAbkB#5@fO1g zEp*z_l>GT5Sb@MrBR|&#BfX@p1Z|A27H~aLaSX3!ctV)>%=+ShaEwHw>DqS}Keg3x z&S8nUS#U(B_P!TOJqGP{LJvC?lk^Q5P5G_p7k8+S)@c((CHF0RWT7*1T6znyvtu-B zjrT@kI&8m{6#8n#`@gEu*2#VQyty3v&Wcc40!=~PgD2_cYDI&VPGMa zf1n!6;4YY?$&-69NvgJ$C_w*`zKf5UFM`Qapvh5Y7=F=wMnBXK^Aiw{JNBM9in)2? z#|X?KiZ@F?YeblY$EB8eGhl3RkRAm?eC)!?(udD+Mi=jh__fd{9ozb_Ygt$Sk zQg2UbY6j~IHx(s4re`aJv?y8BcK0Ood%h8Y?Bnz2j4(Sq(sdqM7~bx0!PS$pg9PkK z9oecOo%@PZ8K}rHH^XYly)aaFwhkl-2}-9Crq&R&s>8plbTE%-I&QsL78@T;z7UPR zmh@kYhP|-IQVdHym>Q(kgOAavep)$i6L-mU=*-1qVTN36D@z$YeWG;Q96?t=xb00N zH6w2y3KQw_%K1q8b(i;JO&JKKJ0~wPdsv#1vJ*Z~Pd6?KBcR3B22$hAkBfu=Ypm%) zQb*-O@IxUrDv6}zf|sQgz8%m1Fd(es;Jsv^*Zu} zF~y(L)K3g`XJ?3pj8A@hP?boTTDft5o*OgX{T#c8&b6w`M#Y!m+$bXt-#=39)G)n6 zFWz0r_|5rjro83wkn1CsKe|$|=TGp;$gQ=ghcjh(%6%+xO7M*}!gYolMeOd$PxqU9 zKi9CjLPgS#id#B00hR=E-(H;7BV|Hi;Y_$>8Mv2>HLWQxFa3Cnx?qCHA((=ZN~jxi z*fbK-(ts^?W^|a8ke{=$ql*_Y%~I!!8cI>y8F?Y1_LwtqH)AWL%y90F9J6A=+tHC_ z5hU&9=`dGgQvI@Y4g6>%h4lB3=naqiYS_kTVO#?eK5L9`YUt=N(@IrZe4u^xYhW>a zP*Nhwj=ZxdC8rU9XGXcv8YZ`^HJbd5eoIiVf+2EDDD#oeT!MH9GZ=#iHc*_6}M9AmDf@-xX~q&AHaca3nD3BM@-Hv)tQ|hTN&Z{VwZ5s zjh9}{(reHpPd2KHCF||?hOZD=++BmM2UGit&v{O}-zlI3$v8>W=~LThjWy&pwmCUO zt}z#Dh>4UNgSEYorvsE8wYI>9nJ_bIgiC%HW-g1T{E8|P{v)BD(_kd6;gm8e6;VPW zqB`M|B9mk%M(G#EMU9C2T-=47cE9v*=3S9T@pv)Z7oF?X#DsWfLv5=xcH_YQfzPB$ zRCdF(ek(q|Lq%J>EQECw*Dki<)@sw}Eu_M?D#Ah%$AsAU$kAI_9f$kV8UU&pbenDM z$axx&fx`5#GYyYTT+R4A5F7aaah-$uzly+Z0?hXPGE)+ZhoDo89ux5!X9wql0D(p^ zT048%Q`=6pv9k(rc;?w*0?zpB)cqX{@wQ(P*No8LL|d$Gin~jNnd20%zx>I=4#&U{ z(h@DoXYukAU`~pfNJ!TtPw|~)ys-134B%r%=zoMMYN~=Hb*wBfw5NN)?@v1wZRmh~ zOq#%5H1RcK{N;Gl?}~NQ|KLu-jk7@3SfC{L)f=jRi|U=O9ceJwN|?!#ocp9)jKy*? zPmx0{SwBcWt8p1;HMpeFzQw~1P#By8ABQy5hcE0W_Yjvlh4FBKKvyK`s;PnE5!Sfn zuX7I~!V7}dkNo?qc+Nb=<9*EyMeOr#aNH}U~U$e6Y8!I$$AJH7vaT7>)}Jp zKrRThhRSHt8RK%aTp(|r&kfg@fyK1WYr^elq<~9sG#|+6g5hX(ZcP+F>JrxfBR*s&|Gg|&XPU!XrISu1dZDbj5>_qVt6Jr zv-Fmcky^|&0H!jzNU^*InYTUqju__X1N)C6$!4kWJ!Xd@Gi(G*;=)L?qxO>$I-7SM zyd-vbi}kixmuJDXuqP#1NkoKXtp`}D@SSyNT41rem#wK__$;$A#|Gl8XZp^DVhO%P zC5cR3_#N#GH9c}1>Y&+V<{MWtf&3!w?w}8;pMt!pxGofnu5Or&juo#%yf)QP4lOh- zt)Ai$UStBV^@08vE9k0M+M0bYE3U;$@l#bUE zLO?_Z!VdtrTX4|CTbq0PTg%!@+1X%^cJ3dOQGKT2SV+^@xy|t0-LQajASMj+os<=k zk*EBgzsdHqmZXb`c|2@PjWn^OWgwm2PcL}kcz#$2qRHD{Kc=n}k=M@7N{XFdF&THS zt4gVdz&F;|a62)8?SbCrNNjdsROPxGz2l>mI*20va*?u<>%PW*Wj4~xr`A*cS1`j8 zrV-^MT{A}1)xkg=cUNenZx}XrB#4RkA+04)6UreoB|0bvu*Bd1nY;}B??47VG%6va zzq}p}#G#%Bd3umvKG?FYkeLbxC&!)DP-`cWUHP(VAPGNmUpYzB0Sl1&bUTEpP$pR! z*n*Z0WE@ZeAtx%RU=WZ`K#zrP=j%Xmq$4N2lhR-tG55!A78aA04`{D0G@yhEx^W|pB z2ru;snvWbHKYV78lPBkOgDEO3M|3Nf#MBhW|1MX^$oWby9CRt!E}t|-?xH;;w+H?f z@_9wAeD7&ymM`{FEVB+^YjC_piXQ2`YjRFPEAzrw6jX^qwKaw%wKeO3xwU`P0v_i8 z$l~g*`pqPW&%xge;_;8wTKNeiL+V}(J+(XcAAeluVnsko@ner<`B-!qa3MU5CfO3m z@8W@%A2l$peC`3)I1C`w>1M37CfJ8=kyUWrzYy=iaOuc1_<%RXzlRcPxWZ@g`va!E zv6sRq;KG`DoY}qG?mp29a^EfDha~}AeLNniF#ay@gZ0yICMN?dSySm>YU4OWZn9=z znntS1IzM%~x$$U-ki(GYvuaniRC!Mro~2!PrD?)R7}b(D_$0eBaF1qoOsfyXh7#;R z-K6Lt-tUOSRb0QGsNh{IUd4P;aD}3zmM*ozd=OO=^QsMw^{pPX3iEMH!J8d4WAdbI zz*#kGAN{qjelrW6;qSRw1+c3w67!KBHKaW%5husT0^30?-nTZcz9AZtM5leKniT&cOL@v?|KS__b_tu`9c z5_83tmp!#X$39uMCJT+NI!hjt_ineIIYc+abB3Js@#06E6IQA=*o<(Xh#I4M}cWA?pZpku_2R_P)DeN1;L zth|fL=!d@%Q+ZimFXW!+hEllXUN}4)N1`jtUDi@44~g%zMWobDdewf#>M8up&5inU zWO#8KQF5>B&2o9@%AZ8_w05mySF&&s+weicso*KA!OTP-C8MumD3{e9@&LF^2>L|^ zw#gOZg-AldX_#%IOd7Xgezn5WsW^5*0`{x66pBark&8jDDWD8q*^730&|o!8FUPyc zUR^je_{`oH#4gKX#V~%o4`U#trp#$@h-TJE?@zAv4+4a?v_^)+;7%?HZ^WP&pWOe9 zRte?!ZhD*A6uhTD7EkU2H1bzRiN%vI=cGcmREQtKa>R8R1u@tK`al7{GcS)txgxb9 zieOw}+PY>}l1v43;IRT7hl(^Gjh}nCa`$q=DsduTnVRBhoJu2o})rfONg8)XXhcFUTGD-ZVm`)hBLBu!NK5XdHJM z5y5;VI6N~=|mk0F+eSm91V{c)$;23}RUeejAN>(Fjkk-qlIoc8f zIaZ`_U-J0KNe(2PXFQW96|a-*s4uemT3qoDs8&|Qx|J?CQ&(=6I>nibN`PjpXon(C;2=GUPY5XAe&+ioky7M69?_Y$s*O!i=%P zG<}$_(gN&z8re{RB3;R1L)|}Gen+~9Oh6ibFZH~QK_2)*bc>fKorD86H0l0KB%COe z&@e(QOp$ZrOqLD~X4$G!g{WGxE-FGF5(xd!mV2-{ME;uloZd`Xq?_}gi~I3wr}<0souT~)ujUq%7(8l|j~mp%R=pcZ zn(|N#{)yIE*kUv{MC?o$$}My216=YW$at)BeQqFg!U?XmtK)e%#A5&VsvVSOF%na2 z;#`aqG*Zm9!(zJi)*4dSWVr6SR_qL5MPD_*^sVYOC{qp#tOVL#8+lG%VT~^>(OK0= zOy`D2x)z7r;0kVS$QYQ&6GpZL5k*$cnk~R>g<{NT2?(dNPy%;wfwK=aXrooHvZmsI zET!YwaBI~kMn9SezM8HY5;TkXqB#HSNrI@Bt5k@w+0Dr&1=9^Ymlt(s*~G^YzN&&R z7+zc7oV@}xQZMZtE}gd?uvBaENok4dHbJ}N>U3QUK``~o-UhA#+N-9Dk(O#*ieH2uq%{WsJYIos|6N53X5X$hmz=I zR4lqnQU=*g3V?QZKzRI2<38|{PbY|TP%iY{E5*e7cU zF(7w|T}Q)#lXgQ_@D!Z*LN~dUaB$zHlOA=TO`u~3KBTZwR7k#2BDAX2V5R_IVCx$` zM5k`egXTueN)L@1r79GjlR0Dz6VV{O;H)iy!wLH-=0(tFeRVo&&dF*L5@eWG5P0Kl z4G~+6_AK_awtcI$r#+eD4)2`x#M%pbNrfl@L9b&6T7J&mk2YwNUKuPOWRtx1>yq5) zw-0Pr@~B1*0&qYo!nlpe^51bZxXNECSa~loAT5An{-wK+;YnGt9tL*5X|}SU`9vfP6^(F(SXR*Fj;CvuC$T);XH4brd?cg+@tSxp;LkfE2f*fj!`fEukWAU7k zuQS5DeH95?Lk*W%>b}GR!}GKfD)6LEm z=b3wRqO-R94vkU$K+WciL+pvnV7Z6F{&0g1Hy)B-ivv^F;oG;oFD(N)g0Ec_*d=;! zo(#e)7$iGo>zu`TD`0ArJqjUXx5`K=DVMs97Z=G$rr2V%=X}fPToiBlkU@WLJ#jk0_P~ zF>SFNlRDpsvviK6)<7xkxcR83b{IAS5F3*5NynhFcZvcGmlf$xj6M3u@8#1+~u)0nz{QsU5s z3m@QfzPZ=Z`?-J_e8^3%FXyELwG*_4e{B* z93tRO2rSyYd*o*8l?M8Vl^i@hA?sfus%HH&;lBbyn{bf+zZs^>!l=DRcYP`raz;|n z$3O8O39pO+c&d-*s$%OX@gNFnc7kUH(D2QiFmxa6~bR;^KWEN8hO~ z_tOeA>&ZU8MulMSVaPLVcVwm<{Ky=tQdJQ_3D3UpI;0cW-l99*=HGHT|Bwm%FWEOJ zr!7H{8B zGuMOtFikW6&h-TuP&f@>YDy~jXd_VG?n-YtVJ)1ZUtfzF*Z!-%;U9VL5XxzH`y$c~ znbHscPLuz=9tVNo@po2nu&_-3lgs*Rj1%-<>3ED~x>A|{H$?wESKi1-Lo@Ure*xkh zp)Gic9`q&3nlB1T|D~*d-KFh)CRGQM~YpN<3GmauOWxgA_<0*$y0W6(`z7E#s7DsciEoA z^O2l!3Xj2Hq=^0kIr6+tu76dh{ae^`amwki7DQ_x2&A!ZV{02i4ia|5%6dlmtCZ+p zqTxeBL+tL_JO=&0X9FDal4c>GY5-5`Y&+zAaj6*TK!A~Oa zm9I}1;zl-B|BL$h=2sECoeCtNzwV93aQ1&|%s+(KiV*3!Z+S)kkuC5)^S=L2;=f~q zhR>1mPYC~GYu`tpFOfpJrk| z5Q0V{3XuN=$2)vMq>w=*8U1|AeGSdcq;@JPr*FKF5pCDsj(i0@^Th`>xCs4xhn8~K z|2bXI8C;MM_50?H>zl^d7XOR<=KwOcRw4v=D-|k32mZ|bC*rOC>Q3U=a8k>Uag}yA zuf6kXAj^n;Zub9ww@5k;jB$U}dH1%bCdR%kr1>S~NqR7&K($&}U*~p;;0adrb|E!q(OY zX}D}73PZ$ac4+I$_>2}(@wk9J_e2c2JNfP2u79&=F#>;kj=SzrE81<7 z!tG;8Sy}&7wX#D*=g+RG{k;;C|b&J13v z&ZE$NQgoY!Oh*cS>2;s3K;rqirk+HCV zTt_$1%)H;LEoFJ#Ylh|Zln;EOHGL%Va%-*j{S&)S#Z{#3lbSLlE%!Sc$Gw(jbTvr9 zTpMGI=#6`?&4u#dBp}ham8OacW?x_5{HN{y+pDeLLvq$l#^vKw7dm;9on@}MyXtbe z0~FTWFW<4GtzN|#+#O%Yk6B-o4VK;4tnF?VL-JPs(qjR5B24ErBz+cv*2B=6u{gu- zBVU)p!FavmUp#RJR96DfXf#0mx86O+?%HSc2l)qg0@P1|{J3y+o0<={&*p>}7(qKb zCJPC-mhL$6?@Cc5M`?}La7JwR;Lg{3{JCby2URUX$&>6M=F=DWIK4`fq&36uE(TRV zb#-+cLSkaz`G#Q|)RC}oL)E;blQj+R(oOQyN)W8C?=_8m!sR#78z}_yjvE=`y^o1t zv8w7{2fpREUk5`UXNJ6bjvg6$16^NdH;aL8Z&(VbrD(S}=~4-zTip;r;uN4;#4)Iz zfQyx>6UV^7qrDCR30W*J)zcQyQ`U{w%Y}oxGHH?zzc_vk>n!!!-IZ0gKU3$ul<;TP zxn=xzI;aMd>yFB=>I}PUlKAGV@1aTj`rg#+y*xMa+FQzxFSubG$o3%rQF69}B>9*5 zr4TMA6}~*LS$DO#=M5Mv;4@3>T`AoB6;u{~M!&Hgo6)Z8cwb2oeX3hlD77V{A245xdG-hgeP&MEAwBXa0vUt$3rf+s~aNYGDEpylN^l6W|N?#h@*tb_^ zb@|0{3jhv(mpTKx{yN%!?wUNhwpml$T(oW^;Y}BKCu#G1@R;q)g93UAo51<&EQH*o zJSB80=@i7zt-UOk5mq&@tk?+hDaAJ``77yD8{~|;Dj5QFg6?iVTs6~fYLYzhSuWLf z`vaxNM=uKIH+A#YJ+C{Z!3*A5e;JwSAd!PIf9Yq4v(YdbJd<`U3Evjy6V>wdh7Ks% z%KkDKTOr+Oe#a+DkpI?~9QQsot_2=vfkE9CaGbil*CrVs>G&Emb^Ev>0qK;43GP_5Rs+U35UH)kx9@$J9xcq8(#l!W2@o3a6W z4D}QKTi0k`NuP97Rk2pRnEb;EbNjk3mzQ|eEvs!yQcTXEMwMSU6dCdj4ddMnuc!r|_TA`3x~LxShiIO*Lj(!kALnK`UuS7D-ZV=} zKmr@Sx)%*S?JVsl0VfR|&bzu$C$;WWos&y}KpY?y{mJFDO4MGjxnR%g+FGi+CV1B8 zy4HU!`?;MNkmgm^crZ7_@tD{npG9>Tk;+%|;svhBtvf!0RRrVO7wQHpF+Q~9`G5EF zSE6v!ai0YbvmCgOr6`%T%^54NZFoESZxF|zwv!}%VP?Q-tXMJK#KJe5RqIr3UtoxfQj;XyvZMja3a9>_4ex4E2$o?Jx8$1)G$rrW;`BXJH-zaBz@xb?a+_V zA0nx~Q|Ht5mFdvW@O=FBeeTg54D1h>EK=TOUF%0LM!uv?xms_I4H=VM8dN4hgXD{7PPGG3pO0FJV>GOV<`s|tG6_gf44FKS0 zzOciip^5t1BI$&tvYnOE*w%%I^iQE0JoEjjjMph`w=Z)OoZtLD$-?UH_UTi8L2VSS zXdpBk9Lf1l8L;hcVw<^agUeM>*o=6lSA?xYsrt-`_#b&gM&Z|$kVVr3@Xs#6T>tL& zh9~~BT&X=@xqi-Bb-rN#yxL@?5nr+=$;tRnEqA3zwfFT3>*wQ}+tIeai^>b(tKUxk z4_-i_zb4#veGTq=@?W^_;!_an^g%Om-2X#?q=E#~B@=(xV)6j#uAI`xgtIm^iX4>H z*TIP9W|yZeqynn1ODE=wmrR6|>!7t&$c>!sKG^HOFPyqhz5iIdekI)vzTR58!$4$2 zm%g68%W97oS%szSbQ9!3DaFuf>>}Rf)n(CJNn`)Br|oWE(&^z{Ij>)IJ$duIyb#;( zA@b58&FGQoPBG*5cix_?H?rP!S0K5SNIgV{)Wr(2uC2JpbhL@iL*n$Gw8XyppDv^7 z{cJRqPTGh4+sCV~Xj%JKrVYF1*k{C5R7)qcI->j0V!x|N$7QfrL|+VIMU){~w7O8v^(Grg z9AgraP|u}~g5oFR_WQ5E6&IX=hLU{L_y!<0I+C6OoHDSfIn7N>dNE|lH`PO z0VD{S+t%XwzyBRyto#nUGxi{P;BfR$8;n!Vx)5icvH)QLPBb?Z;^BMl!f&72jyIP+ zg;S52fF_b$DUz*|V}r2y_A>9lUyDm`uixnT!zecg=jR^s++euki7qp@LYJ|2AJ zahx<~BwTzKXs^w~1HZWg-{!Iz3b$g$<-fsgm!1LUL~9<-WZEe2Op5kvrUZ{w8K9z0J~SN!PSpHi-ltn@Y^dc#2TMOJo4yYar}f-y!_My zc=GM#NJ)%Cix6e%mX{1?a10imel|`zW){K%9Xu!fK-Wz27d&nC_Y_KY4nA0zS#72D zORg$L^7O)2auUB_Z-ON8LXbM^lUQALYhP8^T@~ei*nKTn*MXCx z4Xu1>t*dKLD#c|cSiKy{%REP^DBsE#dr7K^x*ykBCgW497<7zQ=@NBrOXk7|$(HjK zI7gwCFJ<a{`t(*~>dW=To#f_qwKZsTvCUYXz~B%B zvrNtGFDznL%)859$qC6oz47H&j0{G07*naRKMV@f&eJNty9kHKkLLH z{)&F;t}QRbp4@Vb7&VgjD)wW^vXknb$()o&_b2Jwa?c714pMRUbDh-nbkN?4^c~ya z8E%dptiw<=-3!^Hlb*V{cl@n^r@(+Lj(;}{*KNl>_4@U zI1~iro>E>}jc{TgApUlJ7C6zkPjq>%OSwcOxVO?#y@GUpd$35WKg#p>;I$W@$6FtN zt={$%293e2DWfp+^s7KRiHGmH0ULH_bIGj;oP7QzxbW;#5EmX`-2m+h?fcA2$b~GL zzH8klIN_)hk>fsp(y3>laNC!7_pLSjdll(_ehGJ8cL4!uLv;zITx$QwWnaxT0zbm81vb&ZZkrIqp@@2 zm)M-1j$>wyLIACZdHMNR@zfhAnLZag)@(z{X_czX?LJaoUzLYtIbxoyUyD4*^zD%O z=sIcZlGI5}*z4Tfp7Kla>_OK{;_Ul&nV$AVzH=I8>Xolxp`rv6wv#{WTvk|sGOii> z$!mYXhf^*=#*_DBU~Dk0pN&@8`CxMf1moBz4M#H_8k0fDhY5l^C@U9=az&W;fVse_D&RM$Ij>D3n@>)Yj6zIHdl z!)Sr#btuuzJUFV}f%Bi4Pr z0`GtD2{H>x;pZQU;p3)Y(Fw<4#6Z6IP`j8B%YL}_(BLc*gldBz+pJmzSm z_KQYEVGfqO@fzwQ2IK5gjz@GTU6`o5F#S8c`sT+NHgz73n>Rzbs7TGF2wltDQF8m9 z$a!Q1V0(~rJeFvGe?MgHSdTYf{}(>{dIK8yLY$B~6epf`CQe*13(?`hs4XqPKc4t4 zmSu$Ef#2PRLGi)JNY6)LXawTpqT%b-CklOdk8G|k!5fR8#hz*(1oH_a_dcOc0l}dd zIbjOs9yJXiBvdlOB^RovoKi==ba+~T`lL;D@VGL$^OO6X_?`Q+uYB>*fAH?I4LJR> zt1)-{AVoy&?I$0_X{sy72k*X(*Z;E=nT6$ik?_aJDYJ3G1?OYt#NlXf;Y+%diTV}T zQaX43qDu(=p0%Ij>6hQaZ@p$PPs=ZF=g9i+_p>6`G^KmQru z<<-K`Q~|$!6L9yhZo`Bj?AJDIbUN>?)>B)Ng(0KHVd0HW;lszS)sWi6+fiL!2A2mBi~X)OpJCMOpJPkmcNm=z+(+2UJ%jw|;EUIh(srxqedkj52U;PV z{-`RyH8Ab&X`VU58bU0kTwfM#LmtcMFU-8VZ zE{8uSZ^;GQakEqPvI-{`qQi;C%6vTY$gfd8Xe37R?eG4FAH)eW$Dy`38~=FnA^i2# zC3x_bi!pEJ3>-U7NQJ*jFGIH01;Al*-*yz{?nOaSDR0C+h>A@>YHBiXnzWwCkS$A5 zQ(eQGu@7Aj!cbFIfUNvt-mJrslA3}L-XN5PSV$A^6-9Yj$S)=#;e)v!Nl;u=gc|~QEjl!}@_3%od#XK&Cb<#xIT^6dgg0w&X*@G^x zJ#K&dwwB+2-(!8+Nk&OG@x?oD;F5Fx2ZinoUi@&qBCR!Cy~2m9SE%ChrK72yZ5j}Y z*^AD`H4A@+vyVSorC4KYh6q56a_2tgy}? zxGFO7`+IJ~jza5!Ja_t31UrbUgx~?{hAp`J(PArM%!!xbS65$%aQ}AHR21Olr=P$( zAH0kQ7Qct{7tKNcxDZNG*_q+2a!0$M!Aqv0TgyI4(G02I@(&U-;X@c;WMJ z@!BKzVoXvnK6v%7xaY~&F?{N5%osfyd$+8|Bfq~JYj<3Y`+s>I{Mwtb=5PPN^2z7n ztl=RvMVw|TDPtG2$#)0 z6&olqYvE}aks6ARUU&{~y!;$)xbGR9QtE2Jq!y>MZ4Lp`}(v7*t?f0M`wdYt`Y~fP$>ec=E|dF!scAFc(9l z(Uf4Bp;{^=zqPr#*Do`$;O9eD1s->bjZK3R>^=S@`e9h_Xnrk$f4 zOh|G|n>p`sO`NbPwX3H!^YOnvjccPO;Ox^D(30d}c`f6F5LR*h@#mko2{p@5mRt}$ z1gTSR+RC0>rD237Upl?&7t|;Djhl5U{{D|~NQnm?g2Z>#;hj&% zu}ajJIKl8cu>_q%+f7 z>rBtT(zSfsUHIhnXB25YcEQo8s^(iBt%;F*=+8_{Qx}H}k+#T!+I*XLmF&T+b8o=i zSDwNfDkoOC{roflDmV9mysZZY`eMhD&T#cMA=i^raQ5$m^D568s*BXIT=SL2pzE=6J_$wPf1 z{&e@xv1CgNE;?m4HhlU#-dwg5{gV~6_ifi>0BaP_VC;)W~FLMSa7Qh(L(o<^d9Kyvg8$B;36xPSH)%5J}ut_NY* zyLl5&3_uKB3N~|3tffL)n`;a4%CmpLbFaRGb(^vy$fyF?estH@Y4z47;@K4#0{GVO?I*8e zAxY~4PrrflPneFff*iyS8mNYSl~so=&@Lp5Da8WT>Z(VJGaT35zZy6EB^Ex!X;aoblOkh9%;r-z>(pck^pc z#hJMO`e}H!^en9V7cJiXA{CYa9CE+)!QYUy)#L9^{0?{g?m0aF{#Q7D(qQ^~xA27x z*yOI{AD;a;PMk6v)unlO{kg|+>+jhQzuAK6BU6+_w`Epk?TSg~8>Om-x`wn4AwjJT z6?~Cg&6A_?&g(DGsyq@6RmGU|$UV62PcLHiraedvPQ~iCU&oM>uEI-y{1rx}#-KQR z8-9D+`FP>2r?LH_GchSH5HbCMLCG9S;~Tmx=_dO9IeaZ4ibJ$&bkp4zRiy1lmsPg9 zeEPH;d&lW>(n!8^si-Z@#xoDzs7UL*kH3tcU4AyLzD}gybTxiDaW0;?`=^*WXBy5v zYABB7J$KS6eh6|j^93OjsZ>@&OKf^ZCI%(OtCw*hZjz^5LtzQiC=rQQ-g+FP2lYd9 zV*}QH{x+^S|2iyL_61H~I0plw1CW=Mf$h8Zg12#m$0lObh+zmMQEn#=l|?x`mq9;q zjw*5FW5}?PNQe$q&jca88`i8rL3tzHy%N#RdzyqGUf)b@)t&c0DNg|H5bMAARFPJB znfmiX_hG@*5ojhEKmGZ~@sk_x#XXO|fGJ~!Big45>v!iUS2Z-2BR#7CLE$kNGkO$a zIdUh@APF&%;ixUk!^S=_lcvB~Rifzj_qw-+CC~WDV-s?It{;O_#&I?-vk`lg_4;;0uK;t7#E` z0irt%O0v_B9Y*;FW`*JZwJ!G;+9|C3smgHGtc}Jmz?@B-dnjD|Hs}{09aLY;cvTxTDq6+?vO^1 z5(E?kC2T~0J5kghtX~vtuuv(HPy_+#PH9-WbJ_0rzccsEd-uJ4y9??&Bc?=eKG6t%Zw=)_0)4{d~^r4 z?K*(h{xcK}8q`C#W>vUXI87q({Q5~JCSHb)z$KmM7cTlBZ7B+8Li{^cZ zPd#tUp2PM{?0hIJt^eg~-2dD-3RYF|!W-|vKlwBk|HA9Z9v+PHmA7F)hniS0<15^L z@00M4sEDB>9s**HW9`cM7;(o!M6BA0E{!9Zrz`uCkGl#>mUA^MVO9P*kGTdE4|Z6Y zT>6^*%>+E~##i{y$iAuplr2-5!f6VUxVKt5ap@e5I%sHtBx+h(7HTy#1_Pi1-u_|} zzK(2!jXOu6cdM!lF0)JB3?&BRvhKyl^S~QBpa50xLtoU zAhquuPRzLs;At%sLjmG zC(jx?d5Y0>PoCPYJZyeCoOHyg0zM1v*pWlnM`5o>k;3Rb{Ao1pIUGI|+|#(q!)zij zI~j-e?}cwh8RoAfo_cFGhCLe(-=I*WUuGC~H8IrkU%Yr8Ug<1Y3T&6TdLl+GTT7ji zYQ;LjA92pXn|9MYYd-Z;MKb+}yX^Hm5w#s3{(KY-@B9yj-F=7Jsvs*y73;Rbmj`#_ z*qO^HUZErsqc7mQ*KWbPQT;LVzg_WCzo7_k+6J3G7>5Q2VsP;5w@`{Jy&383aYMN)2hPlEIkv*_#;hpa0rD+js1&?6UV?wOv()bfOkpCf3`x8-(t? z|3S1Dp_O|deS!+2@7*J?>DTF)F#lVeJpUiWpWlp@9S5LEv)0(KZl#_617jxQwI@cZ zNw_$QW;G$^6#BPnjT2>hW9yPhsK-g_q9s3|*RZGX^n26sVx@{oYiK9p#*$kZxdxSR zQohk=k74EV<=DO}3V{V9P_%G3N>y%v_DySG=f-7NwfTVBI^z{w1f4o{LZKkpjwW@6 zu&`Zuh%!PZys`mLwV!M?-pF>k3x~I3`oXH0^+F`xdu9+Gduu0(WbMFhPko9>FW-(P zFL%Mds559>jS~g-Z9BKF!^+hga5g5HlZVm>pa9>YQ&$uXNW%1KvytrK%WW=Mh^*HN zE$URXmy6_0wvS|SeBy>Xy36)9=`UsC&L+TBQkk%c2EH&4PNyZtVadW-_~wVjC{wc; z?ixIhD+5K4eEAf9oc9|Vx9^I`QrtsJlR+)+f?2Z=UaKWq*CzfVLzD@F2m8)lYnS8G zuV%rcKzR%rG8m1jm387t5peUPu}@35h{X$j#t(CULPB;Bs@1H4j$L}9W&O&kY%ZNX zggG;(Vcx=(2q{wy{reB(R-Y#DXJ!uX+>9+pE}%i}^7wMxSQKkF6nA&6hiQ|>V|#LG zy!iNiC>myyJGeUV)yETXIK3=JKR5)1xrIn@p>Tp<=gz^|j39LHek;q?&^tzLUyX(9 z4&c@vy-=}aLB&hL#nV`{U>@eq{e>E>NDLk_6djt?Qhsr#4r2Dw4QSWtHl&>1ijO~= ziUhAh=s##M>rqYBe~Zu=bM6@C&YFffKQDuS@krdk{B+^jiU8(E*C{t}Ihqly~L!15qWiBvKL+ zY~6TXu~;wVpKTy58pJ&={3m;>j6((-fKm(%r)YUSISW!HViQ1o*qGy~5t{z>M3u;x zcizF<b)WjT*M|#}DJ#cfZ2tpS{O0Z=+ZJ3M%e} z_$0(!IEe-GW~ldfUVIhfUwaAT#!tZ5Cx$7v1*UaVpL!7=emoHqKbn9pUAic@JyH9S%2}3ictSbl`J?#EGsHD|5)07;WuzqV z;KBhkrFMl2h!hf{spXHO&?=odm-+~P)Yg^w^y7~(`K#H8rr>F4B)GSd;bLPhBPJmQ z1tUsv(5-=lBu+ANWyxsZfz)D0ZC-|_hd+X1eTR*YJb4!Y7Ay`9H*xY{pG)$cmWaW~I zMkCut#C$paVU#IT78NU$LxtKDP`1lrvB7h4QX=Ac7$}}~h;v9*XimmxPf1SX1U8We zXcE=xOEM4A$fQS1N)r94xr>X9XB_5RMq`@2+csg-rp;KkXdb5jyi~b)P%-^Vc=-@DD`^Zr3RkQ4B5b z7>FGUrea|4uDG@L9T@%8D-#rVSIXWFjkD2H^{s&n-E#XV1pW z@43C@wRaIm*L%8kK}cpawR_zuwARNDi`V1u{vCMXfj(3M+|8{N`>ZbZ<}O)_HH&}1E#-iZzF5qy zU2)v!YG_=g-4~~D^302axrp#1qE4SfT2d0v4lHNvI_S;;my2b#$p@X>8l$|fq^zXe z&mP*2fyK+A_rO=VSH2Po`le#&kRh12_OPNJ&FyI?&z!^Bxu4_Cmp(&0SAoRHL_*Ak zsI`b7onBA9g9i11J8x@+`kai*r`q58b_Fh-x`^9uZHdFb|BA=PpTVivjrfsDn?$aH z`Ui%gdB<`%$39TZoX`J@I!)SQ&EXhoqbu>C>2%yZU?dMhaXh8w_VAHoIKwS$L+`l< ztD;V+IFe7rkw+?~O?U{tAqDXB;nG+)^;OiaT?frMR{BQv!LFmm)*$NHk$!AH{`=em z=-77>nzm_$-=2RIw?Fv~5=b%i@?qRH^lnuyDgpjvrKjNYK|`@{#}Ok<)`&2VbNK50 zS6R-tBD`!Qj{Ni@8do2T-6xn1@h~Qcnu7CFcoytaIL^IvUng|$KNO8R-+|#n?|@hI z9(*xRR$hoLh5kEAMq>Ckdobd$r_r%SK_2XGit(RO3q*7A$Zp)x^Hx0i)H7JO>nOgQ z@H`%PWE7?^9 z{O?W53=M8UNX2?6khWV1wp*zf6j|%SvE8_*N;wRDX9I>l`XstHEQvmyTjKSPW-1v% z&hi+wOObT@BO2p^p&6L*>6@tBupNAhmP5?eacEt?3bwP13ls>%{SVxWccw2=v^;F} z^dh(Ybm)C2;xc*T4k^pZw!u2|YutY(hd3RT*546dHNNRICs@+1DsW(qT1ax<=Z{LamM*HWGcSs7Uxr zWBht^|I+327jSa*IjVJ

yYU2=GWlYNjt*wQdidUBLHi4&&_Ui|{C2n4P?cg%nI0 zHefi8YyJgLzjig{=Fb}ok|^|CILDcPp&B^&`wA{u?N@0YJ0k-+u<5{gUVTL^u=JdY z1^yV!Du0=!DjeyYDJ?g$B^oxUDLoTHi$tuL! zgeo~)mJkz*n3LNXrzG08YKZ_Y^QDKC#;ZK+_VgQRT;k&Z#(_dk9!p*fWK|N^?MLNR zXq)nylQ{j!w|77&YD6~1f|cuWYunl=K;cjJ9;-plmal`{R6hFg@g&h39lN$iVGd>D zulBETN!O3sqNuIAFzJWgm@z8Az}ijP!jCTt^TP3+82j9#h$~SMhf=Cw$E#1Fc(5lf z$0i{lh*z;mTtfyEh}54U$wnaM=nA~FV472Q8uuQCHy<6$nYb61%?<6mo8+D1-LVr37tF#E{)u_%ozF3_S4RwejM~A*ov`rNrP#Ue0A_K|zWfQ#U(fv-Rk@!$ zGyV+Hir2y5M|vZST6yV%E}htm_daBsQh-SA<)3>an7A`KPx>igB&<`OZLoN;{>%Q+ z0M_fZ^S;2a7bn_Dj`?g6{?n6v47Fku=Xk)Z5cl@iQT`D;cTlHV1>Q&!$H}SiD0M`z z<&&CQRL;hK9=^{`OIa#)N2{g{krsCtKh8-<^)6Mp+QF0GalBc^-xzo|Z#{)b*qWf{>;n;zr%06=VF!b)+miDGNePjnlJUdC<5O8qQ3jFVruTZdf zNnE;|fL{IkBPfJ3eVQ!hQ~FVjTLv|U>9&bhwg?Brh({{W zlasTRSSnt*q&|7vNc>uV2=@Q<9x4~-x5o=)se6gRk2{hIvm`(0s|kNh3{ufK&6r)YCJ7bp(-x#TFwK*zBsUb1;%_c1|@?1 zu$|kY5+PfEym^p|2Pt_v{Pg~{xcz}Kc<=jP@xXwN93_AzWkb0N^@^$kUV$a?{3~OX zhS2-KH>%&1ObHuCmGec*?hj%`?OvEM@d;cke>X<=Z^QnXdziDmQL>P+)kqXa`!>x- z`I^t;#Kligs!%W*au0UnZqMS>d#|93ZA+4TG)5c2s&s9x)&$7JNft18hUUOVjG0{& z8xNd8qe{has7rm!Z_ov+e&2^0rJIp2;mUnGQcQCs{DlX2$A7mC>-L>O(<&tt?M~D# z%MD1(D1Mze3BTc199-}*Dn^7*Qf!A(g@e)IuHNX;^&-MKkrmUX=P2CUrU<%`$+Ptb z;M?i;RTB%j_3nIDIBHfXtemANh0A&!?!=;RPNDPQ0jM6~gQH8{ z2f9Cj2~Q2@inIjH#)_Z5zz2(KVc)rRs1gwbP+$&7KaCNSW}*kjJUJxEnvM5ntj5wU zQD|2`5^<+m&^c?vbX06_PJp@OrMffe&0Gw- zHYG_LUn?p^J2fbI7}1*g1Q$g7>iO8XWe=+NY{hK=iK?U2(KKK}Tcs}@D3=`qLkunA z)?=q}=~5ypvqGgLrcz7lkL=`V{JMN4E>W{qrEXKyjtpTRZD@F;BbGZmDJBCIf|*t( zl9Q5=!acB}K@2WdgC4tiBLGjM(w3bm@k&vSWaq~#aAb3GnvIrd?b1>+k$QphW`zRm zjQ1mI$5tdU+ZC(Sz^I2tATz|*c3Pi@133GTnV>+Y@ReC0kYn?t*|3k^Lm=%<9#b-@u!X4X8Y;}?eh!yZMgR=s$--wOk~HpjVx zyAbPB0=>Gml?62JG30(Zjs^8v6g4#SJfPuEEp>Y0CG6UB3~}7s_Uf&-qxrBgXjPk- z*_Ny&Ee8+AL@PDsEIt}H1`GD{W{9&#uwea9s8zl&HMg;(ZFIN_2Wc}()h@UaS><;g z#alm(g_C%HEKg30R?9yqoJ&;IDdc!j1I*bAakZDTDSdPP#b5skkJoA(dCQ5f*-ut8 z#N5(#AO>|YIv;SKc=Fk`_;E>;>gyCg_8R1lqntcTebf06yJ*n4W`NfxPC?@;rMR6V z9Xkptno!013+33TiZFtC59-49$%5uew08-vB&0A>1 zNS#QDzlbSQzeAPk)v)Pj$=tT#$^Gq=VAVja%Ya=1CoowkU%ehW(|5~W3N;b&SWNrdZCk1(`s75$ zQEkCZ!KoA-Wo3KK@lf@guBQ)EBmMa%%v||}5?aMQJB<^L)JwM88Tc++0i=F%B63dd zBDYhM^m$)(XapKIjzC1#MKV8KZHFjN;YXVdJE&k_S!eKIsShUz7f$eC>5%6U@#I@L zd+`KT{(2mb4DiB+Wk2vF-@_Qx+YnkMeui8fLJ?P|DI<|5$4=o->V`Io6OJuqE7jy* zHEfz153lmo(UgZ&oej%bO_mzq?bn}FLaX>k6p{(ZX^yp2H5uKEnY^ll8B|hc+O&6~ zs1oz*l=qa-D)v&9Yl8AU;?+_Q>x?+MG16Y7?PMgyVfk0%aL+4W8A7X!&CHUNZ2%Qg zX-OCG+c%%%iHY-+&?;LVGpY zVOzzLao^J?7@etc)JD(~K2-bVvs3^3@X65=xc5$K9_#kQuKCZRK!B7m|G2Gi!-Bbp z>|7rQcWlHFPO$uVrRK#9Kg7;jL!}eb;yAO8VW)oap%Pjpoj`8gk||hXRA@@dYJAvu|Y~#Lj5nQ*d`VmuRu14{qVU&T$H|3)^ZlSpEp+``uCIi%gvH0{tEjqn_%a?8i~NBVM$)p2|>Vl3YLekqD@6-er| z8Yi=oFy*a>(fP6W(Y;00>mj&0id}b%_S#D%rK53gM3BgUA7{dKA}e9WfhaWNp#+%? z=VoMf)1-biJo)_VT+)6A&1;pngClY5>Dvj&iGNQnS5`pl;_OE+?Zfvo=b+-~dr^e@ z=A=@uS+oef?ij9OeErL2G^iYA=RsB@!$Ja~tHyvF+)40diE1)p%D{YMN zpHGD6(bDj(-t1)Dcc<3uC|OZ$jnjzi_;qmTaJy2Q>tL

5V-fPj1J=6v-5Ui*9vLJ^IReprT1O{yZE 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 z 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 BSkM3f diff --git a/contribute/05-review.png b/contribute/05-review.png deleted file mode 100644 index 330cb519ac2c6945b9e480262568025fe49b7c1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29682 zcmcG!V{~TCwlJFR*tYFF9ox2TCmq|iZQHhO+jhrx^7XsVxo7Y5-TU{hF=`d2=cu`= z)~pJXlM#i5!h!+<0)iD66H)*I`uVp2*+GE)edD=G_X7dJpqL8^%83gK63E%xn3!7{ z0|AM_R;ik*DUM-fE5`GQ2|x<*Nt{Y25^1}`<`Upq29l8E4I)5LJ=K@?YRDn}z^*6A z-`4)U2UQ%ZEI(-S^Oy2d5BB1#za<`! z7>T9Kp6NXUArA!5@?gTaJrDunla%R^7-T1yfixxz!amhc=nz|EKgD3%ja)Laas1yX zKooPWT4@MC?(m0eZCr$n1G)T`5oN*uUis3K^*8c_&{Ztn>g zLR%1f9~B?M?oUhvUlf8LTfVUUe!LJE)oZaSe9_=0{xE7rmP>JH^T-P1XM|^1;{5H* z{e9U390XvVp&^!^v-o#&1n?h_RZx6Sp{!cy&;8stwrcOa`@S9f*2Gqq+)>=bu52oV z7Z#kB8#ZijT4uKsq1M5!VU{59&*HDk2RZbhej~qt`w@e*v$R{bPU60HM5W+Jz+(kR z`HiS8L7jm(BeHs@4Ml53dWWM8rPZ*V6MF~jqFna`f=8j^_AC*=8YqD7`T%30Jw3+a zU()oJe)?0kKjmvvKne#~Zdu{&0^}pU^@ZV3DQ69_7K6PqV)j~X9a6Q)H{qWH-GbSN z)m!Omheie>-}kp|;W7!{z0kgSury;iQZG0A>IwtMZE@1r{nyxSX@7jD&9gJq$t4av z1$7kZ!DJBcMd1!O*EYC-3~o!B0l5xfZ7L!z2VHBaKm%EW-h7iZbF<|A^tJfeyGIW6 zYsc$EN@rjP=qgE+)74)6Di)4hhorTjqQ6G~90Leh50Y^oDAN!8=7%2vijXfxEJX1D zGtJMmU;FBMcxo_r{Df-2EWQl2s24z-eR#F_O#Z~XAZ);N{&2Rin?ImtL3Mm}Zr~n> zAq4nOA&}?zVGtPy!R+|75CJ3zkfQmqLL``oL`Xu>lY+@aL1Od@!Iq-G<8Ee?^x^O%&7mqe%L>`JNsLHKZzuWbqij-9-T2I)Pz*YznAIlVxC`(1CoB$UmGw|IO z@enOV)-Z}@gx{ECDCMFCi|0R75I4D$$V`O{uNoUcOjUS!`K+QH_%~shVBTsnI6Urv4gl zpJLCeob{Xkv2a*!p){hbXt8T?VXI$t(>$RTnSM2R7zQqR`FV4w}e)jRDr9~k+)njt<<6#BR8W2P}nK**7-~W z6CThamJ6tBesNz(2NxnkcT4?7kU>5a=JdUEn=<<26;#Qi`07%$WZ^L!5 zbn$orf9iRaeUW`8ym5ok0OJQR1w4X{z_i1r1?vPG3_J#pz~(eGt#)6)I8(l(bgYQY zPz;J$H*S?~mF}$evn{)Z*>&A=BbSF&h?kGKC#WRoC<-ow72ivpOW9;lX0)Y;O|qnC zF?-lp>*LvUZ+6aoqy;sDju6e{Pw!WgZq08nOw`Zcm7}hWFHvp%Zcq+k{(WggTTj>0 zZ4|K1wh?N@vf&s_7-fe|jH$?e985d4yuz~5JpI(Cw!C^%CppX#?ZrOrs5Rf(bTA$L z{`9xhof^Cts|&3GWOx=cp#zC0@@qWRn#8irxL(mD# zW!TS1!QS((`fz3w!kV-N5R{-0H$QQIVs+TH`+l=>-vOHKZ_u}(G_$zBXeuDP$D!Xc zs;NZu2k|{(Vz6djV7|GyOEyNVMjU@Mbf$DhX$=Z#=XC>}09pa9k&a2d)lz>Ye^;0jT@k$m@Z}Y@6~9kvlQImj z(kbq-oU0e*1^re^nHfzv+EKfz^E`+04008Iml#RPQ1PbSMc1Neq^6<#&>Ey}ziIfK zDdL5%l+a%4UUz#;Wt(@tOg!xm~MwsrXv%ugYl-YuVbw>+H&# z@2ochcN4veCResoHubUlENa$hX|H{gj4BkVWBh$mrjfF~uI=8TvXbX?*M7C7=;Cq# zxw_D};(Yz&uHv=FQ!Cqj{aQ2DqqBqG-1F#r?$-rA1*d{zfJbGyZoru50(f)?>)fk>V20vG-cFV`@8Z?ww(Z!Ff?|lK zsKZI%v|&mYAg2|{_GnUhdMRRsO#8eO&*Sqrs*Dwd^_4YeYrOUGkMq^#7iYv({1w`! zVuz}|?zQ(3zKYKxbtbAPJ_whY2gc{kH1T!;dQ1bp&y~hg;8)>c+1|psDcnr7Be;_b zSI%AMdC-HfkL*{@A0L&@Mo+gJKu*uPJF2GO{hC0lKO-;)nO?}EU+H;( zoE$$?2n4y-%A(-{fbzz6=MD#Yd$GNMD5iis<6vPPZ16B%6hLRTT7b;Pu-X$4e=~56 z*eH_DzCPs(55A9_@Lq@Nsj8}9`2GD&fV34;cK`xHBmJlR5LY0%0RsAwW3Hs;s3tAN zVQ6DTr*C9qU`*#~W&0N!2#Cv-<8RZ-*ioOr)ymS^fy0%X=wBEdf7|~I1BeLzh2m(z zO{69*M<8fpZ%n{UM^DEgO`xk@O!OhxH-<8(df%w0e{6Bnzj2#T^&21gcZLA6Y;j3?8xH7e~bJNQuTk6(zCO&{3q#ufc~453-FH#|6$U9`RiY!e;vjH#Rd2u z=kq`b%==jY0r3He3-K$t{5W*WQk@#JRP zNj5tpYp%f0&0UG!Bwy+usz0kiv>^Wm9;uuuB*-%6fUqs;{{{MmWQ$7aLhujHe?b0F z{!oo8FWJ>%`ZtSzfh)w?4F7M|vXHIeO5C6)`ECE3iN7}DONwtt-CR$k7R0~#+=#~V z{e6;5+QXGl?UbbD{HQ1>_{7B_wT#QlEjJVYt@cZSxUYngm>2{R5m7FbvM&Y1F%G3j z54bVmuba~kG zI+|=@hl-X;u2HDW01ZcrvV7-v!lrx2f9fqt;8$PIP=GGSo14uSRIb3e+U>>JY_$=b zo15#du50$kfZ+BGgo>t8PF`L<>$M^n0~Ix>TDyaYi>s4Ixzt}UDuLe|pUbs&+p0of zRr-H9wuc>3ZYC@$s!FR!fxC}Fp{S_H^`dTMw$sglgp?FBD6e^$lFm*3heo?&nY{1Y z^R-PQ)6fd3;Q2g85}5^i75CZMSt`2&*);dFRsn?io&~WLm9N9`WM9|wc0@ETXL>tD z%=#{8pBXMjgEu53WYSNPPGqlsjw8;wmSal5)V=Tk)CtJJoy*ZR6P=^hYk1W`_^)m= zwY^Ne&D-buNM7=_hMmgKgQo({XbVP}zoYN1Z(dSGVeWhZV6d(h%55u=M8dwcwZF7H zE}KFlA{hCcJ{PLBIR#y3bNQWwnQziC(;#3Whn7@zttt&33H!m8SBQ>d@RNk8(w&-C z?PAx-S&xpCiUZcsqxY9tocHruWsK>3W~^aUzeG=vGi3}XaeeS0*~W@_o_FT*3qJQz zIB(_HO6uPl1<%-rWVleK%O;PmrwwuNMIG=?;&q&zo8daB?2hK~FwxM^(gmngI1noM zI7vc9p^;ahmL`kn@7234R_JWcVjs-WEH;{Hv6z1wl_n)6Mc5;S=I;~T6T_sO{?P;v zp~6d|X%4U|e2iSN{$H`+{f(5%BP2Y&($J$2mrtSOW>C5Eh>Dm*@rK&<_@wzVvh(dX zIXNkzAQ%kO$Njt+fJiKYK{`IIx!_bKsJ%x`tuzr~DBY91WZU;&vG`wc=BFD561}bd zBN-@5BjWz+FMdKhOpUl_X4d|{X-hE}T;p+GcdxZ}FpqLC~AZT^AA$mdqF zgo9z`V-*aa*{HjJjUQztz2+v}bUwXyNTNjqqfed<+ueAp>Xq)h{Gd)`t^HG%J(z;L zB=;c9a29X#7H}UTO+f{iVlkI~3DsuDOT%&Ut`uKh2VAiglavSVyuU2m$~P^AC@Rw^ zgfzrlgnLWWblyRc$!1&P^t4r`Bqy7YX=yl}HcDSVLn4zAu(M;5XWIHxaxzqp;AsY( zITDKlOM#Zd*Ofos1)T?)hB*0`6<+w=YBH zO>f5$yCYb)m;SDpifJun#gHSTYR}D)Ma>KQMgu%$VF^sD^~N!ptvUGL=gU>YEn;a% z!P(bS>CBAk_+Af)U~o8UrsUQ|&kiG%JC3D5czczt z&aSi#C)8e1s4@#!?*qh{s4H+a#!sF_HFf>w8iqcuferiXdrgzsH4n@xY|<7N@G-V3 zTAZE9Yxhar!%!vWQJ;H=)8Q8XR>mr1#onX4|Nl=B{~z{NL(cpSxqn<4R;}B!ttApD zNAYce3<2tsR3)%$DpPB{oTGf|RMi4-9r2XUS<=xvGPmj` z&PMHZzJ%VU-#NM--+9lzj_xVnS()D$zwMqA2w6q%H1vjj&LQr+ahR;}i&mLKl!eAM z(7lQNI~jR5x$+NsC$UHBzh5nzBW3TZSX6NdeQvQ_x@$T;W5S4rt{2jFxvo=*uEq-h zs8y<)up3RG1G?fy*BH1Y8r&>P>uKq_8EQj^@H^8B5*z<0vGYU<>rqWO< zS$aVw)IyPvQ>ry8iTug z1~S~tVVCPFD2-e6Yk5^-yt-C>uX1I{RqaJJdR1e5VSH!2px7d%NBVd52kn5cvBOJt zEs9Eq(&=wdW}}a}k(>lGEp`s^qT^29H#QEm%Mv7E{L{$*a5+4jAQ9Mpc`d3OZX*0Cj7n9Y+l@~q^d#W{W8W8rzCQKD%Uj;={8N;-)X z8UU86Uo!R1AQ%F7OaVgoT*nZ& zSIvF3Z-~Kaof$SUJ|Xo{@p-UhxeA8*JE^^1%V_cm6by`jl^h#XxX2qkIs`242w|~T zZ?4b~0Y#1wDrrP$Jo@0RlKZ7Rpg$e1<)Q5eXXI_D#d|PaF{)a-}Cs zWJ_(#xm8WevGc{ulv0x7N;+;vk9-s=EEJugp)I_1ldEAJjDVsIm3v@0_+z zqmf-U6K}!G**6c3gU@%yt&!+X^`M+EUUl~6J=XCYtGpkChSzYDS>Lb>69R~}KHw(P z;KMMSc(B9)6_iX(*1Y6wX)`~81LSlPBd(KahQg&g5J^-@pbVX$5O^)>BC1Al z5Mh+>QzfI?h3&y%FlT`g`B4!f3L!-(@3fXbRClxVDw>7_hRP6Ngp zBNfxQub*jrJT#?Q-T$t>3pRP5Jt@u@X&Wc>XEFAYIUuf|`i(xBZC#L`e-UoZVUwkqAM>@=6rrg@8v&vCZFo z+utC&n`93Yl6N;ts?c>ND};kWfn)K6vm9;Q8mu;vqqcdpU(4W6*8{_}oCpYL(VGuj zFOJTH(>UB1(pW;dLfLiRPO#u#7lyi@lYd^73V#a_<%9LFQ4bd^o{=+~&yzS_uA?R# zah0t#n5xp~t5~J9|=Fb$zuNSj8x2sTKG9evGRppr zbR$OPW+=zv1r_y268XomGzJmTg$x+kh^ZXTwFXI8(W z@fz*bl=S*h$L(aEfSb%@#+FN@4=}9CeBnHLwdP+!BF9rEEHBP2%<*7Lh}=QJ>1BqEn8i!M~%Lo*Ept0yZ^)1XHS)k%2D}c zPP%+GDG(5fKtKal5d0|Ekt{t})+Gh^d|WP*Tj}2k_vouOcDGP>^S;F9 z<;n|@YK!NoxuW5N#RBL+75E~+0^A#mJlu*-T+*Lfq5>2{oE z;ubS~G&eVAw%%A~he8~QnzQm)27LC5f>yTN+b2n+%&}Q#B^Ze_-H@0SpbIAc%iq{- zCMBpBy$fp14*?S|@SzfCF7t?=5_l2ek*L&@T}^0}tfk)~2m-+y3t|L+D%USR6H$d0 zZJjLYwRq%_PWb=;UWkYY@M(W0r-Deh@p@H47|Y~Mk>DXZI-mZQ<^R6QRB zhHlF~BQ_3hvX})+ZkcAfOMM@AsbYh zpQIvYRgsh(2YEi+EVlLPOG!D_hr<5xw5f?N)B;B$Gu)`sLw^^Wpgo6}5iF;0eUtx^lzRuPd3Z3w(;vDDjwY#{RhDUXR zP*t#fmk~;PyJqET}{>r6&yNZbF&3x(mAEKnH7za1988@3iU+O z9$^xak$|bRHuLKN2l&S&)S*|fT*R6hK}ZDT+x`j7Gu!%wgUw^C?tFhs2@^?N)N9}g}uq_~#F$hDE*-oE}!u3t`^Fw*%KFNoB(rx>FOY)`Wj0S@4jHLfzyFM54NaO|>nchpK)G(SbzZK( zE96F6T2DgaWzMWE_CpWTQ42sfKEp4P>{+GZS%Wn=OsF80S42d-0G^oC8x%ASG$keK zEzfQMLPo`~*ehp8aOuyL7Z(?VG)Jn22jI~{otIUfYN#Zq#tKCnaRQ$2pQWG!D;j!T z?Rd`Zvp}G=SY!|}(;)pO*u$m3uSj+gU_54{toJJBP9{T6X8qmP8HDD#flEfVk;@ld zz#tgHV+RP5*dILew`B6G4H%D{aHQ)?cBNvyE#C!h}xNyfcMocNLY>7u7C{|#b+;#%2ANRAkmeP?Oe@lh{}}ozgB#=# zBPri;kb;}pxZ&y~b*9BjJB%&zD6d{@7N&Al=VXgAs?wVS?WCcw_o_n5T2`b?n8FUV}1odTq@QC55g>Gc^jo7l~2s^F` zH{dH1=K7h}A-`D3x$bxo!%4Q~zfDPtKoUMEyED~)Ao~dpZA#PYT_zgSEoisK>@yr> z8Y7Zw7n-tOXFm_{i#M@?zB>e3ZdFO;zNF=9am7Nj9*<`o#cMs-?w~KVVC;Olv2uL~ zsIgn{nX=_|#%IZ96Z6tYf7tF+E!Jheh%A#$?MN zU|>bB`HAVD4ijcu`3or`FkgNzOL_8qa~cj=Y_>xWXE~6yHz%~@^y5srK63{)S;xeG zX3!r@44KW90fw{ak<>L+_XA{23E5Z>2V{AG$>FhmW9zx3JWjX+p*`#TzR_qop8Hzs ze)d?AZhs$21`e{Y+!Ta7AS*U>(j=nljj7(>4qXJT=4gfEA|SYinTz3yiO93IS1&2~Bk%Rkm>a(W8jLPiny zEn(sPQ++nw@XqtRG&K&W>fU4#C@tHwRBJ{9QZ5Dx!LRvi5|c+aGs4Ngo(Pt$HlmiN z+Vk?&rfE=&1D2oT{k3pnJ$^Owqd1QXGS)CbRB5#EV+=~vnS+o29GJ})mK2(}C##o_ zw{+xyp2`@Es89CmIt!Vt)u(Z`L7!0N$4qCkh!%mx&aEs3dWSP2WDwC|AU+I|JZ`;+ z1f~$7Fes3$`|kbWRz^AC2YeK&%eX*wkcqv`k!xtHj zOf$LB!^XdMpd!8WQ$i&@>M$jHBobPks1%x-5KC3sPQ|Aak}1&87u83SNoXwhaf@x_ zgtZ2eg+>($SN)umM-+iODgqUg-twKy6ri*TU#87S)3)}UYrbQTryo3F)YWh(#48sH z3IR!X78w#UI2m4gkh>;#@w{XTzTs^fxko$TxT1RuhJ4-_4m zu-7q6L_0Fned7li?b~^GE;LAAEUG2IM0G>~2=EIa2v9D_Ei zjHFHywtAtC99I5wER7)?4z#FO)BX0F$$Y+0CK-4C4)*)JriUfrd^S(8LM-aoZ4lBp|t*opg$y>X+Ob9iM)K`VHB-g1f z*&NSsMplA*snLJwOoPG=Pf1{*LKeew9smn5CtIibsqBw-|DJ}bq}2AK{OPdd zw6b4f(>;ie-xVI&Tm16j<6?LnOv>hc$R2#Ho}v{5SBLsC!w5JyrtbMk)H8@`3MUfV zsqgwo(dHK*KmMjHL`3L`ebsS7S9UUHhLjjw)16Axqpeow2G#!bC%7v{dU$cBXE@M~ z7=dQOFM>BGI)DM+`D|U>nO1~|mooz?mbC`~#iVf0NA?4^%n#RYY|ui^jsh0I`^9>g z7<>>69c-}tUb9=4mSMN?m{MTuiP4?)PHCO-K!E3S@x##^%@3H9MenU~4Z~}=t@Y2J ziC;GBqOK1)JGtr`*{!?v)O9{v3S75?_hxe(m|hz~2fa@NH^?>ZDEB4E-gUjty)P5h z{a=rgw~Gni!U_}1Y;}^1lbi6=?=3d{ zkuj$Fr>Ts#M@_1Rm+|bbyJP6H#gBq!3whY<%$i|aLy)Hn4bc4o6SrHHF}C-H`1`{d z@CzMB+e@x@dmeLD%1p)5Zm6;|S^*i=?J&~B;q;dU@O8#D6q)mg9ALtZO;CZn^R^^R z(IBelUjJ0jEB!f-FWij-+hEaB8j1)=(Q}5fqAiIkiz!Br#7Ky9d3SuUOvzgU8c85* ze2E2>TV<}7UGRu#8z63&XQPu-q9r)wf@)wT7Z$E^nYM`F={{_kuLG{Ko}6!Hggem?WM$)ud! z_X}qX-daqacY8Df^s)pkosmWa3XbbR*_m#HU4!;ip zp~m}?=^5nIPy*CM9C&ek_N3u|VhIBf?=F!nB_^2M!86cNcRE-WtGv&}1b>2W9-_27 z=g4s8ZhwgPE1Y=c@E~5nc4OdrcOU^UI1$6+I~wiOT0n*M)Jr|JD$IMEeBJ3U4K*)v^21|{Ah#B*6PL;yvdr#}a?M0@}@^bj01s%w0WIynW z8<9#vCp)oWtIxj6c?v$YrTZs5j~ynMW3o$zg1W%OPK0^}yxz%i(~IRX(dI*nkHO^4 z!68`%UwvoU#kwQ(F+e*iu?`rK2(3nEV7k{BJ)0VhMjZ`#leET*IN=cWl$J*rd}C1m zY177z;sAkaeR!ORkKP@gcR{LI+Q1({NzX5Z`76N6zceiat+&x>n3hZO$3H7aHhkP<&djECvWGEuH%fQ85$>c zIBAvQPOhb+x%BF+O1w{9wV3XnuLu3{lMNT%mR7MB!F>L#>Qo-%>7tKE@oE&^!JFhO z*T}P72k))6xYwyI>WbvlA=_RLV%yq&y12gdTpNC$8O9N)WcdrY{hDAqMq1DN^q8xh zklS>BZGsrx3Ml!q<88iJ4|tMJ4_lHnVVB1##Xw04)eNF3OM$vpU|(}Rp2BR^ zPytaefVvsv)fH6uRy-oTH4;)j+$(6&L6~?}O?CWaSNk6Lc}V&&SlA=Q=V|+c$L)YO zwZjOPqY=%*A*fYL%m!@SUO#&>=e}Fp@4mVnl=#h&@5%es`4Si2;JG`_3@baTMaKu3 zl3cp?g)xNKWyYlQX)~cde->SSpYx$=@}xn<$Z%e}r9d*nWVQVbd-MB7(rm6CROVt$ zrIO9j=B71g@r0*1Q!o-KiA)rShGD{OPbr^`Tnqxqij}no0=NBXFqS845L6)Lo@<8T zovnI`i-;=qOcwy1=E0>HTNfU5-#cSwxtc~thqb@0sAk~VfE}tF$vF~m%44ujtwR5* zI-W$Yq7=5Ik5_T_RjE`cmJtpGOkK)aG*-G7V+u6Ui?ooTu85{K-0r9fTu!OrNk=9F1#F7DR(Sop2PrxTr+m!-7KV2qDAsYUFsmy|tK-{tHwEeTUAX>vw^W z`ktG1g4|`TlZ>QnLj(6h1-K?>&ZmN$TqGT^$o|oY_2A&fHi9qL=J%aaBwj2LfN@Q1 zqp^>mi0&Q9r`t15eLMQZ>I}|SXrz*!>IuQ%acQ1iQNj?uD4U07yC|uokYQ4#hH>i5@6C-OJykXlQu?8bl zYBp#bgQ_RPgbM|nLKqcY3!tU%CMpIK(ox~mS#j!zX3jC$pr6#*TYlJ~iexe4ZLK#U zOlTl#G+u}8aSP|gvmXWm)s@CYj5gU1F75Fgzc3`1Mso8cmEx=+%+_hj!dxxHMIo*! z;g*t_ADMSmLusTD>C(9b2iYy7oGXdvrL`Q@0$0B6fqV8iXDmi|FAp*3_}BT2pxJpr z^v3#eBa(Zi5br$FqJI*w5rD+)^HyLtmM;~>8*Ty0DHO`N=$FsiW0i2o@yUD~QB)1* zUvB>v8C6q=W4Z$tpyWO@kj21Dg zr|GUhFJ;33sFcv~k{UZ@0`t8h$o~ zLH#^}iALjIhwg;2y|sysfkFSq;V?p*&& z|ACE#8RdN-TA(hh7?>2Uo5h>BW5U7S1@=|*Pc1n&$6iPIt zjh9weKP1~v8SoamPul2k3Nw>AKno8YhR~7HDKAHsP4s0PG9g4Elf{5oADMq(^!qK; zhL()>3!&cmT6|15joZzgOZu#nT|AC8xdbpqESJbn|0srVr@SjoMtxEhD1*chgsH*L z@2CbpoGSSh-byxx*Ap0yaQk`}i8_z$H_ni08bUo1YdVSL&rs)KP=tO_>M*6~D8WXdXAi+pYJ=(=hKuv=4F;QB2%z z#Idv#R!!WE_;TI&IbR}EZ1kFI~jh9{tGp+{hR z>A;A~@50pt_`XGcvl}L0NcT*3E z;@Q0HMd;}GFf5)#g(~d?<8;6xbIN%8S2uGZ|LX+G*%}kkbIZ*{JUg3`UJ4*R$hf~o zjYgeI--B-lPoYHa0iPaD72GFi$f5Y);6W;IRB~qxJrZ3~K4jn#!I)MzaZuR7M6U>k z4U@E6UHTBTK}n08N{F5^`KU}x9<4y=l?q`EWx)&)jWT+3KKhR6FeNzG${6nti9-HDa3J2l zF=+jc91FE5IBMUwt8H|8Gp6xD%h3`m`16h-gM7I!xIUe^-Uro zxK8Xtr{xMwU2-Q_WN7>~($D0p1m*XH?n!0(aR*g+VpUd;m;!aj-zzU#?q@}R^PyH7 z&7(+F@ha3js|Wl0y)!eJF57Nut+s!^Wq4XO?aRVp^^CLbzq`q&`lLVuTUy{$gGz;I z#0C#F1JX#`8t(Kh_>ZD+2(d=)*zphAJ#s{m?Xn|dSrbLA-;mv%&wL%gU4*n6gaYO| zy==5TQz8%uEv|U!KJh%@ObXI293f#Q8DuM8HyUHM=vtCf-{O*?{<{==Fdy2Zw zk5$-Qm7Iu35apl=8^c<8%_iWPkDX=zaz!+3>nQQ#wapFt}?I)KUj^l#^qI z?oTGN0OLsz!v(8|3!HhjD!0z1cPGGpVg82BbC5%opXzsdHb;I5 z_Wfx^ylp-X62P{@In^T1Xt0wqClA_XYCXizkn%rPYZ*|-y1)zraoS>?Yi?ueH;X56V-K(h>kk@ z$QLp^U&f(Vq7V{vGyzA{u@Y$;6H`!+h@z?w>zdxNoh?hl7`QuP!*Pw{GP~hC~a+?s1u(;==Ltr zO3@#Ztr&{?5Q4$>V!)=7K>KLu=ZbhI`Z^Tl!#}RB}J81d6 zq}1I*9x^!^9>Mcot~4s@FI`I2_Q$t}Ls){`StF|z8u0fDlxDMKnZmv0T%#MBayCs9 z*W;q1Nm$IdvK43W;GY7axbClVrBKK?rj{*{2*|Vz#t31;y=G4;&}ErlxD>z(=AL%k z?7EfWVRi;{h+6JI6xDY}&dnTR~{Z;{-N>qb=4cFoZ z%>DPSuV3f#ncbkY1roP;osbM4NBj4&DEL7FuP|`8hcfopk*H`&wCO8FHQXUm>9}9QaX&KW{H9W9n>G zA@DBKi5L#;usX}uY#3%B^kty9mVFZ{AoEk}w+|E;2gy7T_r5%y zHgMh-%V@ZoECPSlA5&SZ5Zkkzn2C%M6!{UksYpj>$>FMw-LLO>Ox86muk;;)5%iDn zwJ~5SH-9-o-|osE+v|o42kE9GIDydX52-avc+v^8uh;*<_Ix}5Ys8ve*j(_GKTueR zzT})M(>HVs1q@uU-_N;jQh*#69VEEu_O{jgrRgi%(7QRQ(5dcu5URDhaj09a7)1v{#gTD^|oK!2H?3l~lE%=S1f^@pR3F98q)&Fxtv07U3^bN_6EH zuJowUIVE9*o`Kab?T;x?Y~Gm3VgZe?Pd8Y6fwpbFFf)(cfkZBz>AREOF$_=bwCOrU z@%&sv>3rFjbbZTt#^BfjiyHFs$p~y1tm6`m<~?O%`UyD|KZta+*VkmMVKi42mD(pc z6lYIh;>Cpd?e^5;`uR!@6V;lmeKULiynp8q92P7`A|Vmi>EvcT38dalji~7AxloPa zuA&%uv4M!c^9@gfe(qZ0R}$X;PSM^R53g*BFA$q4=CME8;8(%}hK?f3UI!Qqf=Cn5 zza1A^A9pChVv+5OYS{`Kv+0ZwRRIW;z2G=ud2mnTZEHH)2}&~C#XiV z7WahnZw=KczKD`R`M6~qos*r_In_ai-8EB`m(UP5$8H5g9ruKNcRk`+cU_7^cARpc zbhE3Uaw~{m)7JH7%@!4@yT2?jv+h5teus?UxrrqU1kAQQ+p#&Qr7k8vJ~z&B*u@pp z@VSBoJtsAvAdB9k>|~pC_vEtC`LscjzQl)c@6f4wwAD0n?~Es`T!077F&X;s+eJI` zqD2&yIb8Q)kas8H_q>MFB!uC|t66SjQH+GZ@W{|etw~0 zEYq@Z_Pak}5_l`!MX~;f{GA#~SA}%*bhu)>W}I>$tE%PKvi*e+!`-R$!Qz0J9P58h zhZo^0pDLnl3;Hxx-F1@v!TR$sh(Q%c0nqA6gcaJKN`69YH%&=b#%IA!SFC#8y!H06(shcmS5Jq0~)ZeIwb`LrV{J4xtW8F5D zJB`%kZESz@MpQZ}sd>-m(1B6%E+r6MsI!LB>+;oL)WJDd{k zg*_YdswGffXFVl&#KrSnN2N~yH&*`B1D+M?ZH|!3*AvJg0_>HvJ$#t~8)FLUqJg%! zI})M5vP|C)>`eDJf-6wFZ6+Pz!upVLf|P~^21b~4Vl-6sNh+Bi`T0b~{=2+x14zc9 z$uW~OcA;nsCd6xA^CX1RFM>x$CKIr7mT=>Tly$HBgIT%+kEjXKkr#ir=h&RO%}@@a z)@_^r+{mv-)Ad_@0bxq2D*U)}&fZPc2F$B;0oc`1C;S}a_R(kgrnSbTcK+^ue-4fr zB~X|)CeD8IZI>S|L2e|^jDXx?t};FR%@*8XHvUEk4Y1Ge@Y9fJUyuPgR>(Lw^viHFX8sr>}cwMHM(61?h>M zlp%@Y`jmm1J#-wUxbFRuD@V-*f1dzvoII+|=<%FiO9FHog_R~K*=88{T$+{bSbaFw zMt?}o>u!D&4iIh248|Atfs@}KcjXD+gb&v7pS2*ENM=fD*jCVq^?>krE{YJ((1naO z){>u|FwO+aC=!yb*zBnW@xDje#i4tqE7|mPYom*G11LG0lai5*3Tk-J9Azq4YavT4+j?+XtNN0UsY!57~WIQ*JI<|UoZ%3}Zsk9}$qy1Lbe z4RJLb{-5H$GAgd6YcmiC5;V9Iw2?q?x1b@xy>Up;;4Xmx!KH&V1Z|*$1$PK84Z$@u zE=_QEhv|FY-0ywAS@UCN&8#&)di6S0wRi2>RlQH0I{SILgN_yN!2KC_aw7->`y_io zJoT~9zSakSMv-FnDgCXj6qs8wxiFcFmuHZEf5_T=vv&@mx-OtU`O>3*3};8sK{j1= zA)bKhc~b(%%Zs~>%5N{x>rMSBvE8a0rT}iA2e*RhSg@a)Qa8?th=r$nXamE*OH%%e zpMRd1UF3V{S6GPkWJtb^%kE23t1anFTbS9LEyYkx5^`S1wALBFeOAu+Xy=t_QORSA z*lR0_@wMi1b&aSiUOKk>#$EilAb+13t2Q^syg=hNl#gS19$J?4g}L%mL2cV8wzjra za?|~T3;xN6XehKwWon6{U&PO|wRH!#CIl)hx&ZoNvjCybYs-QGx(Ix2NcQd9LBiEF zr-JtxRj?6&e$6^T>)p?CB~hUqA44Abb2<0IUi|R-wgU8UHgyzd9Fu?#UJW>uWqm2g zd}r?RQGjk%T=JUS3d|#5A9FR$S2J2y!8ZHV7mhbB?w>fpGfbTG&3OjAz4-e}7eb$XqX-C4V1=mm<&mdK70kGPIuQq{LyFZN(~5bMu(Rks^g&eJxCg zBw15L+G*QfZMn7xVxFnqV11if^_f|0^EZK5KX}jV@Mjua+}3m$FEUcTc-lL0giqcE zos~0XI=FkLN@ec+3Fz4JPQQnaK9@3S0!dEVy-FN#tCJ3%cp%u%dhQ+8#Aqh}oYZaKZ}0Z@`e8FiJp z%hZ_Po(ONYDEp$HuPEQC?woOwQL1x`+yBN2gRn4JE%56P@GqrVFJp3_34n!T3iaYD z$1QR)v&wmg>bs~~xgNTX3pkkyo4p;tsq2O(m?wsbjC3))FnX4<=g*Mv^uo2fFN{$b z8@#PHI(Y97^iZPYY}r-^qQn(n{SGL9JJ3wWj;$X#7)!#7p(z7+28)!`bywnk1`F}V z$+*~@&xG_gDwwUo1cK9TKQmsr1#p5Jrtp3%C(QlQD zmG3AWZ=kE;+>pi@ip%x%ykoXx`rT*N2dc(RhDm@CZ*9$9i`#gsqUOTh{+u4@?~|9s z@DkbWvb%8%<}5Pz(x&!G2vwh*boqW}{A6L!X-a`9E+&V8hz*k>N9pBRM4(O-F*G^10e1-jlKYu>6}K-3HbMV z-m_o1D%fHDKYX<@;d>I;AuUog6n6Rb)qP6^pOqZEt5WRL=()dNerdBUnD3qm z$J1F)ed;9QH094OYoagP0kF!-WLFLu0Ebuc;!m7D<2fxZRL?@y5=x~mv7C7PM&mFx zhd8~>^z(t17h*TkYbBvFf4T%x37Ld+amz%myZee%w3DH8e4;ms;*WHHQ`pR>!SW0|u`a59+lJEE(Ll{$AsF zs0S$GRlZ7{6K>mTfr*a@9Ju6*2PMy;&V21`cU@$?@(DLB8Ej!x1SsVMv3=n+;j;}* zBxEl`NBmgM>&hIONvJ#4qs;~D47X&7A9awBh4s5O(q~Pv_Uf|ag$05op}$OtE5s2L z%FWi@uSnt}s95f3qT7svFP40sK6eFd_~_kI^hV=Te5`$El@Lf`RnNG5fZa#j?G;G;ubmnrnu*rQjZKHW?j>>IFL8&}qy`Zdm`+u5&YX`c$(VRt2z^q;{2 z%c|d;C-U`(Qu7w1Z$!uhLFiVax$#fed0rc#=M03k>QfyfCFsO6tBNPPo*WiyeJeba z>mQEc8y4>3JkuybxKe}Z1?4cF4A~pjJHkrq7uh#3eM$&{R`$@>$2bJE*RK`N(v~xv z1=P@sD%Zt&v*LA_th1PEZ0wT?l|<~?p>i|#27HhNiCpIotf zLltmiyWR&GD175JoBrC+BLz%hmj-v5>D)cxh^cL%?f#xvO~eB>Hy$8fj55t^d*x%n z@!{9A;+Q-5OkA;T;4R6%K8!2yK*EM5>5Sm~02s%6;Ju#I6S*p_`Ll1c}XW5&AROU4LYuRW86ue%Xz0wHQQ=tm#~C<(yS6RJKY>> zIO?G~I-O7(@Pu3CC&su{V1@=TXy@A0{@DMqGpI@CQp;HCUIN$7-_+|qxV{RhMf`Fv z?W`T=^RdbXM_0R7`J-mH2tSEtR(3>{xQyq=QWVcyi3TO>t*+$Bh})<3zut23{v{{7 z!mq2J?^9~q6=I8in#^arHX_4GK?>l~@F8YiSBxCNml7YO@t+ZKl>}=f6z6Co^j1t$ zcN(49EwgGRKbK&s4t)5=kqC4w*aA5+qcl3_c8HHp@^Unv0SAolb$W^4|7M~B7fVsF zXN*^L8kX1I!U2I(Cl{l5tQ7W5HQc{Fiz?f|VV&vIyrv>xds@r;l8?J=V&dz>VeX|D zr5I({@UBSFL%knSyV`W?W10%ZI12=uWCl!lQ&x={oQhM|hFgcg9Rs46+QEK^a-^2J zh|Mk<)JL&%DL(9HurjTbidAWSC$Hd@=CCuy4vj zE)oxU^L@q0xdYv*-UONI?4#tjNcufUXCV8TuIc-zy>UpUvw+Ni>zl?BaDB?izVpn` z3HW#$f5^_;voqOUrQ)2|57;+-vS%CW7G)n?n=&(@47zgvIhb;y;*O=_gnHnuH)>bO zorYHPSJhyalNv{cmJv}&%V3tS@43Gpa3uqgX14eKyk@+5V{QU_gBXrx&s|*r&XQQl z(iJXfVA1zWl_)*ky*jVy6oCnJ%nt0@=2?%_7my6Im0{K8^NN-Jk+1sSmLESEOqq9Q z3g>nkPfFog*I084u7~HakRyBAi%ymj<}mr!z_#>H&aQIaPfcSNT&eoB_7f+Ip90NG zE1?WJM8PDf@XsE0N)EOFBn0v8Q-$2!b_CYCWp5nJRfLFvk+JLYt&5(ClL!mFYU@*d z+pWVXn2A)u>6m(ciF@X3`5H;pR4I0F-4NaZhpDa2-!Ms4wUg4yKd?v+$#Rn6tONX! zxHsM>BR5qA?ssDv4bYAyW!bGCxA<)z4cDM>c2*=#QqA%I7jm-G(4}TDt)Ql~veV$i zdk-J<@(*A$(i#`rdT6y42^Q7=7g&@vO8}4|0D=pwTy<(t>JYQ-D_9hkdW2W>XY@z1 z3!HVZI&rmZIZEVpATtG8hCsKwGAmz4L?;C&6;pFxo)zq|NCm#CgZGg&m-~ygN*L>j zn;y0v?=AU1LK3?%5B+;97xvQB857-I% z0msttNLCp~7Pq(Qm1n@YyYZ2K$4!6zNp-;{R$E_^9D%PT7taA|OB1Ms*g>9ENgC;VLs zdA%Eu1ovs-DsyJ4tplP_qvSD|Ri{6q-M+Z<8*bHc_Om*hF$TA=Bu1j}!E1n)vcgWb zZE3WG>A*)=RKc33f8bhFfwQOoiwhEttmL_)J1|F9=gd*jQ`?#^u$A}SM3|i^^a=i;||J=j);e`ma+n(Qv(niR+DhJd36xhl zIhB0surTi$mbHF!Q*qr<%hvCrx>D=AY zL8|uW(F|Q1&xDxVqtcWii>+AIB~$#(y(X{6WDlC8J#qmTxth+QwT{yT2a! zkyIz{H@z+PwaG^Lwcn!EIP#d zCh1(s7Glv)0%?}mkW8YKS3XHiNlS|wN*AJvrof+5PR{hDc_&2eb#A-*a{x{{H0y4# z0A|D2F}E*y*B@eQpN$^dku@ToY;aQQVD6*Rp{!Sq<&@W3g9LHc4yGL(U$`g#8hG+)|2UWm~J-ty1}T$+~{HEKq`^`EsZNDX-zj!U(k zh(b|r%t2@3e{OJl(e_XpJktG?yZI5VdHZ7_iiYR`N_~ugua{?i<*Vmnj`gIeJH_R# zlyK9)mZL~bSSh7C4c{%BmZ&s8iw})ie}7h)S}V8}aTB$7yK4(8euLau^AQ&B+C}ZT z))tV|b6u6)8ei=+6glkjx6Zr#j)Pvu(G?uY0X_O2Bx0rNV&><%4MM)^=o$wNWe=IQv(z9u&zkng14l@|}F4*%(<=jn{{zxF!~r zSMKgL)W`ZBqZ3P8i+%^NH{31nh7%CsD5WbfGE=m`8qd6M-}Iy7Hi2Natb9jYQGngE zd}PY1O6-Cy0Z_nrZ6!(3H?7>+lU5+l_`a>=R^m>t1#h;16CU8vf3oanB1jzPBqf}yCZ9O9Bd@kj-F)W}=oN{<+Zj4}m_;_=kgZw-R?I-ra;?>_V zR#QKkIOf2ehS42JVxWhJp_@3ox9U#Ukydgl1ClN!G(#$V+6LbK;X&-~(a+d}X+w1MA#CM7dH(Qzz1bQa1KAc(`pCHeNkuL4QPo{y?%doL?+m!!Do}V1eE?s}Yw+aOMz3V=BA^U;GCrdlQTMta zsrv?(gpCc0nz!aVM8)exmEb3HGPM1Q=KKz!XC5ll9OA4fso3ltwS#;j+E#k4^1iP6 z;nyt&KmJ;BE zmREj?Sx8E6s)Ri-ZRarVzi?MzYsy12=;KIiOO6h+zt2yQE7nm7^3cl5ue-I&-6)U2 zruE|BEsHg}9djG_ZxPP44Xw~#U2UeqJjC)n2MHUhrc5?TG0;$NZ`(i$r*}$F*38t&X`ifl_|?-odU{~ zS5Tm*kq|MM*!v6e-FhS|EDP)nFEi$GUY7R1SnyI(QYsYxFwy_DpEL#UO2&fS(w&}F zWhw~69*<6v`mfh$V&@Ittnk0RF)h_nlc;rtXHE6t`PGb12?EPOq#sk_{!QcK%zU_$ zD6KMb%ieUZy+bMP{jvu{=M+b}yf4fyajF;<87VW7uQHUAaT?;gnG-&m_l9i3f}JM{ zl9cp$&gmlKu3KCbdeRISx0$ZUsT3U3$i#+ISZA0Ya&-I3>z8tle7B&d6Rp#lVUPrK zj%zhgIW>=sGL;-})KdK?;R=!ssTYU}CS~Jbr1d%6gn}4&d7mL6B;RX)>c@ZW2oWuB z+83=R{#j!jnZt03j8dtxLI#ewr_mNyj399fRW|EXgndRv#$V?*%ioL3zI)Q!An9kG zU!2c5rRT|TI9$yBr}L4cc6;5f5sx?qMw7lc>?TrM9^@P8PB9IL6tJKA%G}cW@g_}H zxY50rS+eu{(ihz{A5O7{+mj(jQ3SV1^Yktf9rvTwpl&t62zj&P0ErU>ddmy(e9S}A z0)Z&_tjvZpM7|0+WzA$NMo(tTguJEkUS=iXJ}cMc&>?x{*!kaWagJe9FH&-`Ri$Y{ zMl*HW9DE`$t!S8*Z4S7fk~q0R+lHJU1efqVeJO>|>c~wL0dwMR!{z+%D&L+IjT$3U zi5d<&pK1U#qdv7ia?=h*7@F7KPx1cGLv}9ttDB=lfOt@bGJ#i@hHY-B;{6*FvpkC~ zC}AN%<-8^C_b*!QT`{sED_hd4fuVwE$P#p z5sOZQJ{z<-0@V_C5E?8e955SNDKPm25=B(1>u#pUTvEsX6B0!dSd-n@@!!35=%&<; z+ycvSwcWZ_Yn8XYeI3$KCig3OF&>eKU#k1#wD8n!U@6q?-+WVl1(Hb}RPY3aWw4O-Nq91iwsB|Xx%<%X)FWM7yMy6@E*?`Q* z$!9saxzx;|FipRH0kj~+ocr2$d%=x=#@+6uk6H$r9GUj+Ea<@fOFccFbnTQ*L|aUZqBLk-tyhOqFp zD{DDc#-W+Uf04$rJRH~(v3FB7$U}K9$Wt1gpXMvdLqra2ek-OCHFAG}nG1y;&G(*Y zaP@0{s?Pz}U>*!wcjPVbXi3?X=DKA zCuIrfnwYF;cWMuLY5n6!BnjH5VkMeYlXcg4jhODv4z(3>+3<_!!;j^BJoPHNC&Ml) zSfsN#Gj;0ueUcmB8RL#s#=5A2NKrS6n$4ck$h?x03%LCTlDrHx^YHCtR3d(9Kl+~E z-h|m>g@RZ=4xO$o>U;siOiSIG)3BNXL$IVL>X*GUK#XWd?;~h*5;U4Wv^HHK*2Q_3 zdj9o?j?$dOlKyWm(iy9&izL5BrN^iMd^Y?uE-KpD>Mmj{GU8PIx!3;VSZDpi%Hg~M zuB14?Doiq_y;6d_pVdrk-X=z%4DqFKIe9iu2a``KCsVlT$}lZ+?a@rcl}T6npR+J=q5?SNd=+SO*JMX?{OO~s5>wnTk?FIT zu`#b=^i6(Oj{vy16kH4%0rJmvz%&~C%27`>*zwO%EV+7r$G^vXns~r~{hT_fG;kU{xKfH5r9 z@a4)kQtzV)CnWEVp0hLsY4ZbdZh~rWRjnBAUQ`w8?Ztj%!&)C(RklJK$AQJydYZhe zE$=f^>y=$GNN;Se+@1*!l}cjMaza6?bU=@w5q}lY_4y7c6L!>q7{Ol-30#QY!#E+3 zlUL!CIFY=j8y0oI@x9m!4|!xNVkYml%z-a>Ybw)qFt zV`Uh-(i^J2hX1;6-4py3;w`6#*4CH-gFq101|%*uy`Sf*MQv1^i};OoYfz3Qx7^ZG zx^BclirMx={qiCe7wjABlAQW04jhpc@Ax3N9PN59Uc+V-Q&wdef(rQznn3v|Ngw~uNRNtQK%Uu>SFiV3YAQMBU{^*k@! zq^E5$$!p%Tf+k^ z`!{uGAP!c;8^7KP$m2~z?Pih??iR9g@c`BYN`>5)Zd7Gdf#_v{w+=qjrkg&SQ3BQ) z?vI|tHsRE(ijx(@wPDq_I7?1B{=j%~?IFE?Z+y8NM|KD=ka|_!K+ajPCYM~@+4-u% zZ{eBI$wkW1dC6LXv$oSj+WpoT6pSy)X(b;VcKx;m`G?(EcJw--vGw`;B$8CdelxoSMa{exD@CDvF!r|%!L1g3`C-+M^- z7VyhzOnH7VdLZeE4M2HeiCVd({$sgT+P{R;I+?b!#>-Tw!Lq!O4D|N;Xn$5VX(_0?LVEt8pK24UQ2 zA;-svrW}=>b8`3bzRd+5ie6l)$1||Cs&3#XGy}UA?2i)SKs~1yCY@drv>0hL;VJhg zA+SecUt@H2p>HgW~ zU4B$<*ZCG_-Zl;g-1TzaF4Z!|K9iSKyDrPrXYlR&T*Wz%!q>jcsE;`jc%52^HD{jj^x^u}{F@|Zctx;&m-q%Z}*fTFY| zfJrn=9o#qor`kA~j|rKsW~DnS1$Cw6xg8#4a)g>b@}wr_i2qz$v;`nZG<0qNI5*W< z%s+nU*kYw|BJM!UV|Q=dqrF4*T98C>Y8Aok3daHG^+*b@eh#vkVWKn;dqePy?b>#c zw)x>+l&QO(sF5aIOEEKozLHZHEiBs)Lex(C_2IsL`mEv~=#M>HuSyKz z7dh|vmHRfZA@E;&=R?K#zc*=FT-<1#a{c@a8d6xq59xx4$>#kXpXuv6>dJdGD4^}p z&|Lm<-Q0nKnE~x9#O!L?4L9t4`Nv2xE~#Ifpp_)U?jPeug@@*Q#_=RDg%L5}ODECw z^>J=C%&So5&Cw!0mOCg&Sf4D%!xbZjc<{_nFxR$6lL<$H2&%ft90h|^n%|L@TwdGH zORfm=M-a4e87$>851|#6S4e+&)%-d?e_z@)oMn@#2*bn=pQhqzB3)}|(hI{w^r^Qu zSb>2O#8Mxc9}xzpcP%)f%)5{UZ>o=osJq+YV`IyH_}m-cT!?&K2{Q;&aM!Pq_NCsJ zm49yg^=GJrK~drw4AH4c?0}XAA&6G7pR(9H7AMw4doDlgv!Ihg&!T{bMzZ0&KWS+* z!#~v>irA&2UBJO_YeHFA@_lORe=lOil@U!x>XZDt6ZszlwRGaq`Bhr#{#S(5lreW= zo>1`yM$NWBbjaW}QJI+6SHPF|N_KPT1tu=M0p4eCZfjiGf<2>LSz!`x0 zj8J~}-ReK|#%*3m?%_$Eee+c&l>!HDNP9ar=P>$W!@j4HyK*2g2`RmH3BcgS(`@Z} zPsx_m-myxF-}(1U`_gcGaQR5jsqI4-k%`W9y%YV$$4zYD?wjfhQtt!b0ZyF7ve#8T9Eb>Gz#V1`ja>$h2|t)~onNONr#thmOf64XAfF zDQnu!izcB+Q+*yy$^kC%BYWVFL1y(aE7FP~ZVn8pTL@4=$zNLMr24$ON> z;1yPPrApiEO-$(Kzp8M=rLF|%_Y94MwiJyXE?9YL0`cALnfu?l%i>T7JRy+Z4guwp z50Itd_PQ7s0fEVK1}H-RkRZ3yy+Spa=%ULlZBt_Gf<+MjuBAU(p@mFR>ft}Wzv|)N zRUILM(9Q&yehn?+zN6_1H;$B*_rHByDt6Z6VU5$?cF;t1@D9{dfwB;bkJplH^XpYF zL1jByu1@;!llw&OjsCJqY>nK`Zi_S#!x1^4d#ywp%;>UM8`u@;mesWdUx;pwnDYMJ z*oP>Qppb0+mj9nQsgwVUh+-rr8sYU>hiqLuTqY>KvIa(l!p+#4F}}04(C`D$wDEzue+$s zvhMPN*J4isiG9Uxx=6!KIUGp=OnZ4aS8Jh?zz1!vnsTf1=9Ia=*Tx|Yza(VEh0PyK zWxw7bKHZ!_CzNrgNLlYIlllH_tg@Mg(y~2U6&C?|90Wqpw{4C%F_Y8qifcI!}E=$KD;J!kvHGb2#c6~)zSM85^3=rMgQ22AWqPcF$K;7-=%Q!%%?Fo3QiE?< zh6CMM(mS^3_->hpZC>RbL0+W2H=OJS)6I#pS6dnP**UXCKvm7=dGK3PsnT`(5WDN{@p-`EAT#&_U;G{ z+9@j!FzCeqZSzUIIr}Zt3JoZQN4G8Ip$n4Fg=^O?{dl#Q>M7WyzE$IuDo|KD(5w2| zL81ld`>`MB@}cZo-|PNXwP_}NcL>ajK>m$Z82<$f5-XlH9!sw3#o(SZK!;J3Y<^5zg6<7}{cWG8lv518f%cM!b1(n`fk zN2{_aSE@{HcNiQFRLdM4xC?~$Ho*Zh^m#7xQdo~VreMIHQ8oL zaMOJ~R(p>ruQp!qgzakQLyaW|?RJ+~-3t%CDBKHt_wQrb-!+0d82Z&ZcPN7E`*<)w z=Q~L%{ z?r}MLI;5aXz#iPX<(nzR_dUS=ihWiKbtrlqm}2l=i%}^YGE=@dB9)ykcu?W%j{qiEu>^T6NEvqYy6EO23y+c1&fr@_b3f5F1ZsU`5w2VNZ_s1+bW-uFJy{9BM zy=CKh_;R5O^%2BRs7Jl}me9H%UC*Qg{CZ0wu;Pgy7T_P)o6#l-OSwElr{X%%s{k3> zPdiwJG!3lA=kC-O<5{!UTPnD4nt*aMg>WJl!K71g!ya*GpXrkw4q#>pTd{v!zdV|t zF6VAov3{d`-}atm6+^g9d7)|m?!7O08=2P7E$#18T1h2|ZM>K|o!c%(6W+7tR**mD|w)N6n(L1(gr!k+aD5O8=o%b*YNxyB*7O%C`;csPlU3pgkFi52` z%hy9@=!iOe$54|nVm`+nM50EdTvpAbnz0QLFLPjrn@4z@%GSd216q>nu7BReo z!ixERZRhOd#x2&oIIccx#@?Y>iuYE+<)aDbG+g=SOo3FFUby~%;1^H8i&jUhev=kU zwX;SS=hli3+GX$5Zhcz(BkSbvC7b-m@8L&NM<^br^Nxw)p9kVb793YgK74AeRM262 zh~UQjYyLeLq`!PWijC_Wnw;<^NY&pBxpS3axt4|i^h~f`#S}zD!Z5P+1kr9(ZcD0o z_kdQyPVYejC9sPlB&%iOh?GZp(b?DQyKbJ~PpeDdka(RU&0<$J4x%N&zOksc#g+}} z1yI|b!~xZES@+CydQ0bFAGm=1#p4UM6ySGihEZHSFqThcQcH-K8Xb1Q_qFcQ~nWB;A;pfT9JtNM8j`< zrFLNLE&6z?_eD{?D`Bo=wqJ)Wq4c95{K!W#+p?~V4Ka<+mo1z8j~t~)kv$=$EgpNc z|MmU%1wo<0CwiS&()UQ2zl(ytK9XS%>tIK&iNAg*^y;yXWWH0r=>IDe{$0d_60D6A zqVq>wI-3%CEdWgV+pfRWBTXZJQv65!le7Tx+O7r={YMn_epJ8mvw99ILd0LVKa|`Cit&0~-rq~bQO3@Nb#~o*V%ST`NuZBUQgonw1 zheYMPq_->~K%#F}jaM)WjVu3vWX)Uhf9o>LMYL$675O&oOcMSnwPR@ioFQPomi@xw{|FEvXHG?51n|d2lOf2NrrqcDko&U| d(lBr7V!E%h(NC9T{`%LQ*Yc`zNXF*i{{hx|4`=`Y diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index f5a4f8724e..52bb75dd37 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -31,24 +31,7 @@ about things you want to implement. People proficient is certain areas of Scala by simply posting a message. But the most efficient way to connect is to cc your message to one of the go-to persons in your area. Here's the list of people (Github usernames and real-life names) and their specialties: - library: @phaller (Philipp Haller), @axel22 (Aleksandar Prokopec -- concurrent & collection) - specialisation: @axel22 (Aleksander Prokopec), @vladureche (Vlad Ureche), @dragos (Iulian Dragos) - named / default args, annotations, plugins: @lrytz (Lukas Rytz) - macros, reflection, manifests, type tags: @xeno-by (Eugene Burmako), @cvogt (Christopher Vogt) - type checker, inference: @odersky (Martin Odersky), @adriaanm (Adriaan Moors) - language specification, string interpolation, value classes: @odersky (Martin Odersky) - new pattern matcher, implicit search: @adriaanm (Adriaan Moors) - partest, Continuations Plugin: @phaller (Philipp Haller) - error handling, lazy vals: @hubertp (Hubert Plociniczak) - backend: @magarciaEPFL (Miguel Garcia), @gkossakowski (Grzegorz Kossakowski), @dragos (Iulian Dragos) - repl, compiler performance: @paulp (Paul Phillips) - swing: @ingoem (Ingo Maier) - scaladoc: @vladureche (Vlad Ureche) - optimizer: @vladureche (Vlad Ureche), @magarciaEPFL (Miguel Garcia) - build: @jsuereth (Josh Suereth) - random compiler bugs: @lrytz, @adriaanm, @hubertp - documentation: @heathermiller (Heather Miller) - cps: @TiarkRompf (Tiark Rompf) +{% include maintainers.html %} Martin is the one who submitted the string interpolation proposal and implemented this language feature for Scala 2.10.0. (TODO: how to choose a mailing list) @@ -56,9 +39,9 @@ Therefore now I'm going to [the scala-user mailing list](http://groups.google.co about my issue. Note that I put Martin in the cc list of the email. If I didn't do that, he would probably miss it in a bunch of emails, which get posted to scala-user every day. -![Posting to scala-user](/contribute/01-post.png) - -![Response from Martin](/contribute/02-post.png) +

Posting to scala-user
+
+
Response from Martin
Now when I have the approval of the feature's author, I'll get to work! @@ -75,7 +58,7 @@ Log into [GitHub](http://github.com/), go to [https://github.com/scala/scala](ht button at the top of the page. This will create your own copy of our repository that will serve as a scratchpad for your hackings. If you're new to Git, don't be afraid of messing it up - there is no way you can corrupt our repository. -![Fork scala/scala](/contribute/03-fork.png) +
Fork scala/scala
### Clone ### @@ -329,11 +312,12 @@ This part is very easy and enjoyable. Navigate to your branch in Github (for me and click the pull request button to submit your patch as a pull request to Scala. If you've never submitted patches to Scala, you will need to sign the contributor license agreement, which [can be done online](http://typesafe.com/contribute/cla/scala) within a few minutes. -![Submit a pull request](/contribute/04-submit.png) +
Submit a pull request
### Discuss ### After the pull request has been submitted, you need to pick a reviewer (probably, the person you've contacted in the beginning of your workflow) and be ready to elaborate and adjust your patch if necessary. I picked Martin, because we had such a nice chat on the mailing list: -![Assign the reviewer](/contribute/05-review.png) +
SAssign the reviewer
+ From 42987ddbaa2ad4e53ca1f2a05cbcf961040b881b Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Sun, 3 Mar 2013 14:49:30 +0100 Subject: [PATCH 0012/3075] Fixes to the wording in the hacker guide. Just trying to clean up and fill in holes in the hacker guide. Review @xeno_by --- contribute/hacker-guide.md | 47 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 52bb75dd37..db7b64a820 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -5,45 +5,46 @@ title: Scala hacker guide **Eugene Burmako** -This guide is intended to help you get from an idea of fixing a bug or implementing a new feature -to a nightly and, ultimately, to a production release of Scala incorporating your idea. Being able to -influence a programming language of your choice is amazing, and I'm excited to demonstrate that it's easier -than one might think. +This guide is intended to help you get from an idea of fixing a bug or implementing a new feature into a nightly Scala build, and, ultimately, to a production release of Scala incorporating your idea. + +This guide covers the entire process, from the conception of your idea or bugfix to the point where it is merged into Scala. Throughout, we will use a running example of an idea or bugfix one might wish to contribute. ### The running example ### -I like string interpolation a lot. Doing debug prints with interpolators introduced in Scala 2.10.0 -is so enjoyable that I often wonder how we ever lived without that feature. However there's an annoying issue -which I occasionally stumble upon: the formatting string interpolator `f` [does not support](https://issues.scala-lang.org/browse/SI-6725) -new line tokens `%n`. I could go the mailing list, ask to fix this bug and then indefinitely -wait for the fix. Or I could instead patch Scala myself and get the fix in a subsequent release (nightly builds get produced, well, every -night, minor releases are pumped every few months and major releases happen once a year). The latter option sounds cool, so let's see -how it works! +Let's say that you particularly enjoy the new string interpolation language feature introduced in Scala 2.10.0, and you use it quite heavily. + +Though, there's an annoying issue +which you occasionally stumble upon: the formatting string interpolator `f` [does not support](https://issues.scala-lang.org/browse/SI-6725) +new line tokens `%n`. + +One approach would be to go the mailing list, request that the bug be fixed, and then to wait indefinitely for the fix arrive. Another approach would be to instead patch Scala oneself, and to submit the fix to the Scala repository in hopes that it might make it into a subsequent release. + +**_Of note_**: There are several types of releases/builds. Nightly builds are produced every night at a fixed time. Minor releases happen once every few months. Major releases typically happen once per year. ### 1. Connect ### -Sometimes it's appealing to hack alone and not to have to interact with humans, but in the context of such a big project like Scala -this might not be the very best idea. Our community has people who spent years accumulating knowledge about Scala. They might provide -unique insights and, what's even better, direct assistance in their areas. +Sometimes it's appealing to hack alone and not to have to interact with others out of fear, or out of comfort. However, in the context a big project such as Scala, +this might not be the very best idea. There are people in the Scala community who have spent years accumulating knowledge about Scala libraries and internals. They might provide +unique insights and, what's even better, direct assistance in their areas, so it is not only advantageous, but recommended to communicate with the community about your new patch. -Typically bug fixes and especially new features beging with posting to one of [our mailing lists](TODO) to find out how people feel +Typically bug fixes new features start out as an idea or an experiment posted on one of our mailing lists [our mailing lists]({{ site.baseurl }}/community/index.html#mailing_lists) to find out how people feel about things you want to implement. People proficient is certain areas of Scala usually monitor mailing lists, so you'll often get some help -by simply posting a message. But the most efficient way to connect is to cc your message to one of the go-to persons in your area. Here's the -list of people (Github usernames and real-life names) and their specialties: +by simply posting a message. But the most efficient way to connect is to cc your message to one of the people responsible for maintaining the aspect of Scala which you wish to contribute to. + +This is the list of language features/libraries along with their maintainers's full names and github usernames: {% include maintainers.html %} -Martin is the one who submitted the string interpolation proposal and implemented this language feature for Scala 2.10.0. -(TODO: how to choose a mailing list) -Therefore now I'm going to [the scala-user mailing list](http://groups.google.com/group/scala-user) and will post a topic -about my issue. Note that I put Martin in the cc list of the email. If I didn't do that, he would probably miss it in a bunch -of emails, which get posted to scala-user every day. +Since Martin is the person who submitted the string interpolation Scala Improvement Proposal and implemented this language feature for Scala 2.10.0, he might be interested in learning of new bugfixes to that feature. + +As alluded to earlier, one must also choose an appropriate mailing list. Typically, one would use the scala-internals mailing list, as it is devoted to discussions about the core internal design and implementation of the Scala system. However, since this issue has been discussed previously on the scala-user mailing list, +in this example, we post to the [the scala-user mailing list](http://groups.google.com/group/scala-user)about our issue.
Posting to scala-user

Response from Martin
-Now when I have the approval of the feature's author, I'll get to work! +Now that we have the approval of the feature's author, we can get to work! ### 2. Set up ### From 2ce31f91a6ec123bd020250ab5987b1894775881 Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Sun, 3 Mar 2013 19:22:57 +0100 Subject: [PATCH 0013/3075] Continuing to tweak the hacker guide, and to add info where needed. Review @xeno_by --- contribute/hacker-guide.md | 100 +++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 43 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index db7b64a820..4f8ca20604 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -9,7 +9,7 @@ This guide is intended to help you get from an idea of fixing a bug or implement This guide covers the entire process, from the conception of your idea or bugfix to the point where it is merged into Scala. Throughout, we will use a running example of an idea or bugfix one might wish to contribute. -### The running example ### +## The Running Example Let's say that you particularly enjoy the new string interpolation language feature introduced in Scala 2.10.0, and you use it quite heavily. @@ -21,7 +21,7 @@ One approach would be to go the mailing list, request that the bug be fixed, and **_Of note_**: There are several types of releases/builds. Nightly builds are produced every night at a fixed time. Minor releases happen once every few months. Major releases typically happen once per year. -### 1. Connect ### +## 1. Connect Sometimes it's appealing to hack alone and not to have to interact with others out of fear, or out of comfort. However, in the context a big project such as Scala, this might not be the very best idea. There are people in the Scala community who have spent years accumulating knowledge about Scala libraries and internals. They might provide @@ -46,26 +46,27 @@ in this example, we post to the [the scala-user mailing list](http://groups.goog Now that we have the approval of the feature's author, we can get to work! -### 2. Set up ### +## 2. Set up Hacking Scala begins with creating a branch for your work item. To develop Scala we use [Git](http://git-scm.com/) and [GitHub](http://github.com/). This section of the guide provides a short walkthrough, but if you are new to Git, -it probably makes sense to familiarize with Git first. We recommend the [Git Pro](http://git-scm.com/book/en/) +it probably makes sense to familiarize yourself with Git first. We recommend the [Git Pro](http://git-scm.com/book/en/) online book. -### Fork ### +### Fork Log into [GitHub](http://github.com/), go to [https://github.com/scala/scala](https://github.com/scala/scala) and click the `Fork` -button at the top of the page. This will create your own copy of our repository that will serve as a scratchpad for your hackings. -If you're new to Git, don't be afraid of messing it up - there is no way you can corrupt our repository. +button in the top right corner of the page. This will create your own copy of our repository that will serve as a scratchpad for your work. + +If you're new to Git, don't be afraid of messing up-- there is no way you can corrupt our repository.
Fork scala/scala
-### Clone ### +### Clone If everything went okay, you will be redirected to your own fork at `https://github.com/username/scala`, where `username` is your github user name. You might find it helpful to read [http://help.github.com/fork-a-repo/](http://help.github.com/fork-a-repo/), -which covers some of the things that will follow below. Then clone your repository by running something like the following on the command line: +which covers some of the things that will follow below. Then, _clone_ your repository (_i.e._ pull a copy from github to your local machine) by running the following on the command line: 16:35 ~/Projects$ git clone https://github.com/xeno-by/scala Cloning into 'scala'... @@ -76,25 +77,25 @@ which covers some of the things that will follow below. Then clone your reposito Resolving deltas: 100% (182155/182155), done. This will create a local directory called `scala`, which contains a clone of your own copy of our repository. The changes that you make -in this directory can be propagated back to your copy and, ultimately, pushed into Scala. +in this directory can be propagated back to your copy hosted on github and, ultimately, pushed into Scala when your patch is ready. -### Branch ### +### Branch Before you start making changes, always create your own branch. Never work on the `master` branch. Think of a name that describes -the changes you plan on doing. Use a prefix that describes the nature of your change. There are essentially two kinds of changes: +the changes you plan on making. Use a prefix that describes the nature of your change. There are essentially two kinds of changes: bug fixes and new features. * For bug fixes, use `issue/NNNN` for bug NNNN from the [Scala issue tracker](https://issues.scala-lang.org/). -* For new feature use `topic/XXX` for feature XXX. Use feature names that make sense in the context of the whole Scala project and not just to you personally. For example, if you work on diagrams in Scaladoc, use `topic/scaladoc-diagrams` instead of just `topic/diagrams`. +* For new feature use `topic/XXX` for feature XXX. Use feature names that make sense in the context of the whole Scala project and not just to you personally. For example, if you work on diagrams in Scaladoc, use `topic/scaladoc-diagrams` instead of just `topic/diagrams` would be a good branch name. -Since I'm going to fix an existing bug [SI-6725](https://issues.scala-lang.org/browse/SI-6725), I'll create a branch named `ticket/6725`. +Since in our example, we're going to fix an existing bug [SI-6725](https://issues.scala-lang.org/browse/SI-6725), we'll create a branch named `ticket/6725`. 16:39 ~/Projects/scala (master)$ git checkout -b ticket/6725 Switched to a new branch 'ticket/6725' If you are new to Git and branching, read the [Branching Chapter](http://git-scm.com/book/en/Git-Branching) in the Git Pro book. -### Build ### +### Build The next step after cloning your fork is setting up your machine to build Scala. The definitive guide on building Scala is located at [https://github.com/scala/scala/blob/master/README.rst](https://github.com/scala/scala/blob/master/README.rst), but here's the summary: @@ -103,10 +104,10 @@ The next step after cloning your fork is setting up your machine to build Scala. * The build tool is `ant`. * The build runs the `pull-binary-libs.sh` script to download bootstrap libs. This requires `bash` and `curl`. * The majority of our team works on Linux and OS X, so these operating systems are guaranteed to work. -* Windows is supported, but it might have issues. Please report to [the issue tracker](https://issues.scala-lang.org/) if you encounter them. +* Windows is supported, but it might have issues. Please report to [the issue tracker](https://issues.scala-lang.org/) if you encounter any. -In a nutshell, building Scala is as easy as running `ant` in the root of your clone. Be prepared to wait for a while - a full rebuild -takes 8+ minutes depending on your machine. Incremental builds are usually within 30-120 seconds range (again, your mileage might vary +Building Scala is as easy as running `ant` in the root of your cloned repository. Be prepared to wait for a while-- a full "clean" build +takes 8+ minutes depending on your machine (and up to 30 minutes on older machines with less memory). Incremental builds are usually within 30-120 seconds range (again, your mileage might vary with your hardware). 16:50 ~/Projects/scala (ticket/6725)$ ant @@ -134,34 +135,30 @@ with your hardware). BUILD SUCCESSFUL Total time: 9 minutes 41 seconds -### IDE ### +### IDE There's no single editor of choice for working with Scala sources, as there are trade-offs associated with each available tool. -Both Eclipse and Intellij IDEA have Scala plugins, which are known to work with our codebase. Here are +Both Eclipse and IntelliJ IDEA have Scala plugins, which are known to work with our codebase. Here are [instructions for Eclipse](https://github.com/scala/scala/blob/master/src/eclipse/README.md) and [instructions for Intellij](https://github.com/scala/scala/blob/master/src/intellij/README). Both of those Scala plugins provide -navigation, refactoring and error reporting functionality as well as integrated debugging. Unfortunately this comes at a cost -of occasional sluggishness. +navigation, refactoring and error reporting functionality as well as integrated debugging. -On the other hand, lightweight editors such as Emacs, Sublime or jEdit provide unparalleled scriptability and performance, while +There also exist lighter-weight editors such as Emacs, Sublime or jEdit which provide unparalleled are faster and much less memory/compute-intensive to run, while lacking semantic services and debugging. To address this shortcoming, they can integrate with ENSIME, a helper program, which hosts a resident Scala compiler providing some of the features implemented in traditional IDEs. However despite -having significantly matured over the last year, its support for our particular codebase is still far from being great. +having significantly matured over the last year, support for our particular code base is still being improved, and is not as mature as for Eclipse and IntelliJ. -We know of both novices and experienced Scala hackers who've been effective with using both IDEs and lightweight editors. -Therefore it's hard to recommend a particular tool here, and your choice should boil down to your personal preferences. +Due to the immense variability in personal preference between IDE/editor experience, it's difficult to recommend a particular tool, and your choice should boil down to your personal preferences. -### 3. Hack ### +## 3. Hack When hacking on your topic of choice, you'll be modifying Scala, compiling it and testing it on relevant input files. Typically you would want to first make sure that your changes work on a small example and afterwards verify that nothing break by running a comprehensive test suite. -I'm going to start by creating a `sandbox` directory (this particular name doesn't bear any special meaning - it's just a tribute to -my first days in Scala team), which will hold a single test file and its compilation results. First I make sure that -[the bug](https://issues.scala-lang.org/browse/SI-6725) is indeed reproducible by throwing together a simple test and feeding it -into the Scala distribution assembled by ant in `build/pack/bin`. +We'll start by creating a `sandbox` directory (this particular name doesn't bear any special meaning), which will hold a single test file and its compilation results. First, let's make sure that +[the bug](https://issues.scala-lang.org/browse/SI-6725) is indeed reproducible by putting together a simple test and compiling and running it with the Scala compiler that we built using `ant`. The Scala compiler that we just built is located in `build/pack/bin`. 17:25 ~/Projects/scala (ticket/6725)$ mkdir sandbox 17:26 ~/Projects/scala (ticket/6725)$ cd sandbox @@ -176,36 +173,53 @@ into the Scala distribution assembled by ant in `build/pack/bin`. 17:28 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scala Test 1%n1 // %n should've been replaced by a newline here -### Implement ### +### Implement -There's not much to be said about this step, which is bread & butter software development. +Now, implement your bugfix or new feature! Here are also some tips & tricks that have proven useful in Scala development: -* If after introducing changes or updating your clone, you're getting `AbstractMethodError` or other linkage exceptions, +* If after introducing changes or updating your clone, you get `AbstractMethodError` or other linkage exceptions, try doing `ant clean build`. Due to the way how Scala compiles traits, if a trait changes, then it's sometimes not enough to recompile - just that trait, but it might also be necessary to recompile its users. Ant is not smart enough to do that, which might lead to - very strange errors. Full rebuilds fix the problem. Fortunately that's rarely necessary, because full rebuilds take significant time. + just that trait, but it might also be necessary to recompile its users. The `ant` tool is not smart enough to do that, which might lead to + very strange errors. Full rebuilds fix the problem. Fortunately that's rarely necessary, because full rebuilds take a lot of time-- the same 8-30 minutes as mentioned above. * Even on solid state drives packaging Scala distribution (i.e. creating jars from class files) is a non-trivial task. To save time here, some people in our team do `ant quick.comp` instead of `ant` and then create custom scripts to launch Scala from `build/quick/classes`. * Don't underestimate the power of `print`. When starting with Scala, I spent a lot of time in the debugger trying to figure out how things work. However later I found out that print-based debugging is often more effective than jumping around. While it might be obvious to some, I'd like to explicitly mention that it's also useful to print stack traces to understand the flow of execution. -Docs. Right, the docs. The documentation about internal workings of the compiler is scarce, and most of the knowledge is passed around -in the form of folklore. However the situation is steadily improving. Here are the resources that might help: +### Documentation + +There are several areas that one could contribute to-- there is the Scala library, the Scala compiler, and other tools such as Scaladoc. Each area has varying amounts of documentation. + +##### The Scala Library + +Contributing to the Scala standard library is about the same as working on one of your own libraries. Beyond the Scala collections hierarchy, there are no complex internals or architectures to have to worry about. Just make sure that you code in a "don't-repeat-yourself" (DRY) style, obeying the "boy scout principle" (i.e. make sure you've left something cleaner than you found it.) + +If documentation is necessary for some trait/class/object/method/etc in the Scala standard library, typically maintainers will include inline comments describing their design decisions or rationale for implementing things the way they have, if it is not straightforward. + +If you intend on contributing to Scala collections, please make sure you're familiar with the design of the Scala collections library. It can be easy to put an implementation in the wrong location if you are unfamiliar with the collections architecture. There is an excellent and very detailed guide covering [the Architecture of Scala Collections](http://docs.scala-lang.org/overviews/core/architecture-of-scala-collections.html), as well as a larger more general [Scala collections Guide](http://docs.scala-lang.org/overviews/core/collections.html) covering the sequential portion of collections. For parallel collections, there also exists a detailed [Scala Parallel Collections Guide](http://docs.scala-lang.org/overviews/core/parallel-collections.html). (TODO double check these links!) + +##### The Scala Compiler + +Documentation about the internal workings of the Scala compiler is scarce, and most of the knowledge is passed around by email (scala-internals mailing list), ticket, or word of mouth. However the situation is steadily improving. Here are the resources that might help: * [Compiler internals videos by Martin Odersky](TODO) are quite dated, but still very useful. In this three-video - series Martin explains inner workings of the part of the compiler, which has recently become Scala reflection API. + series Martin explains the general architecture of the compiler, and the basics of the front-end, which has recently become Scala reflection API. +* [Reflection documentation](http://docs.scala-lang.org/overviews/reflection/overview.html) describes fundamental data structures (like `Tree`s, `Symbol`s, and `Types`) that + are used to represent Scala programs and operations defined on then. Since much of the compiler has been factored out and made accessible via the Reflection API, all of the fundamentals needed for reflection are the same for the compiler. * [Reflection and Compilers by Martin Odersky](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Reflection-and-Compilers), a talk - at Lang.NEXT 2012 in which Martin elaborates on the design of scalac and the reflection API. -* [Reflection documentation](http://docs.scala-lang.org/overviews/reflection/overview.html) describes fundamental data structures that - are used to represent Scala programs and operations defined on then. + at Lang.NEXT 2012 in which Martin elaborates on the design of scalac and the architecture of the reflection API. * [Scala compiler corner](http://lampwww.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/) contains extensive documentation about - most of the post-typer phases in the Scala compiler. + most of the post-typer phases (i.e. the backend) in the Scala compiler. * [scala-internals](http://groups.google.com/group/scala-internals), a mailing list which hosts discussions about the core internal design and implementation of the Scala system. +##### Other Projects + +Tools like Scaladoc also welcome contributions. Unfortunately these smaller projects have less developer documentation. In these cases, the best thing to do is to directly explore the code base (which often contains documentation as inline comments) or to write to the appropriate maintainers for pointers. + ### Interlude ### To fix [the bug I'm interested in](https://issues.scala-lang.org/browse/SI-6725) I've tracked the `StringContext.f` interpolator From 023f0b01cdca944b429348820aeed9de4766521b Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Mon, 4 Mar 2013 23:36:44 -0500 Subject: [PATCH 0014/3075] Final tweaks to the hacker guide. Mostly wording --- contribute/hacker-guide.md | 45 +++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 4f8ca20604..bd7ac60e71 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -182,7 +182,7 @@ Here are also some tips & tricks that have proven useful in Scala development: * If after introducing changes or updating your clone, you get `AbstractMethodError` or other linkage exceptions, try doing `ant clean build`. Due to the way how Scala compiles traits, if a trait changes, then it's sometimes not enough to recompile just that trait, but it might also be necessary to recompile its users. The `ant` tool is not smart enough to do that, which might lead to - very strange errors. Full rebuilds fix the problem. Fortunately that's rarely necessary, because full rebuilds take a lot of time-- the same 8-30 minutes as mentioned above. + very strange errors. Full-rebuilds fix the problem. Fortunately that's rarely necessary, because full-rebuilds take a lot of time-- the same 8-30 minutes as mentioned above. * Even on solid state drives packaging Scala distribution (i.e. creating jars from class files) is a non-trivial task. To save time here, some people in our team do `ant quick.comp` instead of `ant` and then create custom scripts to launch Scala from `build/quick/classes`. * Don't underestimate the power of `print`. When starting with Scala, I spent a lot of time in the debugger trying to figure out how @@ -220,10 +220,10 @@ Documentation about the internal workings of the Scala compiler is scarce, and m Tools like Scaladoc also welcome contributions. Unfortunately these smaller projects have less developer documentation. In these cases, the best thing to do is to directly explore the code base (which often contains documentation as inline comments) or to write to the appropriate maintainers for pointers. -### Interlude ### +### Interlude -To fix [the bug I'm interested in](https://issues.scala-lang.org/browse/SI-6725) I've tracked the `StringContext.f` interpolator -down to a macro implemented in `MacroImplementations.scala`. There I noticed that the interpolator only processes conversions, +To fix [the bug we're interested in](https://issues.scala-lang.org/browse/SI-6725). Let's say we've tracked the `StringContext.f` interpolator +down to a macro implemented in `MacroImplementations.scala`, and there we notice that the interpolator only processes conversions, but not tokens like `%n`. Looks like an easy fix. 18:44 ~/Projects/scala/sandbox (ticket/6725)$ git diff @@ -242,7 +242,7 @@ but not tokens like `%n`. Looks like an easy fix. start = idx + 1 } -After I applied the fix and running `ant`, my simple test case in `sandbox/Test.scala` started working! +After applying the fix and running `ant`, our simple test case in `sandbox/Test.scala` started working! 18:51 ~/Projects/scala/sandbox (ticket/6725)$ cd .. 18:51 ~/Projects/scala (ticket/6725)$ ant @@ -266,7 +266,7 @@ After I applied the fix and running `ant`, my simple test case in `sandbox/Test. 1 1 // no longer getting the %n here - it got transformed into a newline -### Verify ### +### Verify Now to make sure that my fix doesn't break anything I need to run the test suite using the `partest` tool we wrote to test Scala. Read up [the partest guide](/contribute/partest-guide.html) to learn the details about partest, but in a nutshell you can either @@ -283,26 +283,25 @@ run `ant test` to go through the entire test suite (30+ minutes) or use wildcard testing: [...]/files/run/stringinterpolation_macro-run.scala [ OK ] All of 6 tests were successful (elapsed time: 00:00:08) -### 4. Publish ### +## 4. Publish After development is finished, it's time to publish the code and submit your patch for discussion and potential inclusion into Scala. -In a nutshell this involves: 1) making sure that your code and commit messages are of high quality, 2) clicking a few buttons in the -Github interface, 3) assigning one or more reviewers which will look through your pull request. Now all that in more details. +In a nutshell, this involves: -### Commit ### + 1. making sure that your code and commit messages are of high quality, + 2. clicking a few buttons in the Github interface, + 3. assigning one or more reviewers which will look through your pull request. + + Let's go into each of these points in more detail. + +### Commit The [Git Basics](http://git-scm.com/book/en/Git-Basics) chapter in the Git online book covers most of the basic workflow during this stage. There are two things you should know here: -1) Commit messages are frequently the only way to communicate with the authors of the code written a few years ago. Therefore, we give them -big importance. Be creative and eloquent - the more context your provide for the change you've introduced, the bigger the probability that -some future maintainer will get you right. Consult [the pull request policy](https://github.com/scala/scala/wiki/Pull-Request-Policy) -for more information about the desired style of your commits. + 1. Commit messages are often the only way to understand the intentions of authors of code written a few years ago. Thus, writing a quality is of utmost importance. The more context you provide for the change you've introduced, the larger the chance that some future maintainer understand your intentions. Consult [the pull request policy](https://github.com/scala/scala/wiki/Pull-Request-Policy) for more information about the desired style of your commits. -2) Clean history is also important. Therefore we won't accept pull requests for bug fixes that have more than one commit. -For features, it is okay to have several commits, but all tests need to pass after every single commit. To clean up your commit structure, -you want to [rewrite history](http://git-scm.com/book/en/Git-Branching-Rebasing) using `git rebase` so that your commits are against -the latest revision of `master`. + 2. Keeping Scala's git history clean is also important. Therefore we won't accept pull requests for bug fixes that have more than one commit. For features, it is okay to have several commits, but all tests need to pass after every single commit. To clean up your commit structure, you want to [rewrite history](http://git-scm.com/book/en/Git-Branching-Rebasing) using `git rebase` so that your commits are against the latest revision of `master`. Once you are satisfied with your work, synced with `master` and cleaned up your commits you are ready to submit a patch to the central Scala repository. Before proceeding make sure you have pushed all of your local changes to your fork on Github. @@ -321,18 +320,18 @@ Once you are satisfied with your work, synced with `master` and cleaned up your To https://github.com/xeno-by/scala * [new branch] ticket/6725 -> ticket/6725 -### Submit ### +### Submit -This part is very easy and enjoyable. Navigate to your branch in Github (for me it was `https://github.com/xeno-by/scala/tree/ticket/6725`) +Now, we must simply submit our proposed patch. Navigate to your branch in Github (for me it was `https://github.com/xeno-by/scala/tree/ticket/6725`) and click the pull request button to submit your patch as a pull request to Scala. If you've never submitted patches to Scala, you will need to sign the contributor license agreement, which [can be done online](http://typesafe.com/contribute/cla/scala) within a few minutes.
Submit a pull request
-### Discuss ### +### Discuss -After the pull request has been submitted, you need to pick a reviewer (probably, the person you've contacted in the beginning of your -workflow) and be ready to elaborate and adjust your patch if necessary. I picked Martin, because we had such a nice chat on the mailing list: +After the pull request has been submitted, you need to pick a reviewer (usually the person you've contacted in the beginning of your +workflow) and be ready to elaborate and adjust your patch if necessary. In this example, we picked Martin, because we had such a nice chat on the mailing list:
SAssign the reviewer
From 36ce3092e825d72b9b2af3b68b2f78dfd7c04b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 7 Mar 2013 11:54:07 +0100 Subject: [PATCH 0015/3075] Fixed a build error Maruku did not like that big HTML comment, for some reason. --- contribute/bug-reporting-guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contribute/bug-reporting-guide.md b/contribute/bug-reporting-guide.md index a60fb15b07..345dc03034 100644 --- a/contribute/bug-reporting-guide.md +++ b/contribute/bug-reporting-guide.md @@ -10,7 +10,7 @@ The Scala project tracker is located at: > [http://issues.scala-lang.org](http://issues.scala-lang.org) - +{% endcomment %} From 3a415b797a650cfd06f80b1d771822651fed0866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 7 Mar 2013 18:27:20 +0100 Subject: [PATCH 0016/3075] First shot at a 'community tickets' feed fetched from JIRA. --- contribute/index.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contribute/index.md b/contribute/index.md index a92c5f37cc..14a4117631 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -44,6 +44,8 @@ Typically the scaladoc tool provides a low entry point for new committers, so it On the Scala bug tracker you will find many bugs that are [marked as good starting points to contributing ("community" bugs)](https://issues.scala-lang.org/secure/IssueNavigator.jspa?requestId=12111) or [that are not currently assigned](https://issues.scala-lang.org/secure/IssueNavigator.jspa?requestId=12112) and that you could pick up. Once you decided on a ticket to look at, see the next step on how to proceed further. +
+
### I have this idea that I'd like to add to Scala, how do I start? From af5a53cac3e5dc217f2c73f662a95374833ab6e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Fri, 8 Mar 2013 11:14:27 +0100 Subject: [PATCH 0017/3075] Added a dynamic pager in the community tickets feed. --- contribute/index.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contribute/index.md b/contribute/index.md index 14a4117631..05696f5165 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -44,7 +44,8 @@ Typically the scaladoc tool provides a low entry point for new committers, so it On the Scala bug tracker you will find many bugs that are [marked as good starting points to contributing ("community" bugs)](https://issues.scala-lang.org/secure/IssueNavigator.jspa?requestId=12111) or [that are not currently assigned](https://issues.scala-lang.org/secure/IssueNavigator.jspa?requestId=12112) and that you could pick up. Once you decided on a ticket to look at, see the next step on how to proceed further. -
+{% comment %} Keep the space in the
@@ -40,11 +32,10 @@ title: Contributing guide ### Why contribute a patch to Scala? Just to name a few common reasons: - - contributing a patch is the best way to make sure your desired changes will be available in the next Scala version - - Scala is written in Scala, so going through the source code and patching it will improve your Scala-fu - - last but not least, you will make it into the [Scala Contributor Hall of Fame](scala-fame.html). -
+* contributing a patch is the best way to make sure your desired changes will be available in the next Scala version +* Scala is written in Scala, so going through the source code and patching it will improve your Scala-fu +* last but not least, you will make it into the [Scala Contributor Hall of Fame](scala-fame.html). The main Scala project consists of the standard Scala library, the Scala reflection and macros library, the Scala compiler and the Scaladoc tool. This means there's plenty to choose from when deciding what to work on. @@ -57,100 +48,37 @@ If you are interested in contributing code, we ask you to sign the which allows us to ensure that all code submitted to the project is unencumbered by copyrights or patents. -
- -### I have this idea that I'd like to add to Scala, how do I start? - -The first step to making a change is to discuss it with the community at large, to make sure everyone agrees on the idea -and on the implementation plan. Starting point ("community") bugs are usually uncontroversial, so you can jump right -ahead to hacking the scala source tree and filing a pull request. For larger changes it is best to announce the change -on the [scala-internals](http://groups.google.com/group/scala-internals) mailing list and get developer feedback. For really complex changes, a [Scala Improvement Process (SIP)](http://docs.scala-lang.org/sips/) document might be required, but the first step is always to discuss it on the mailing list. - -Contributions, big or small, simple or complex, controversial or undisputed, need to materialize as patches against -the Scala project source tree. The [hacker guide](hacker-guide.html) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. - - diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 08f5d40c09..ecdbd2fc27 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -30,7 +30,7 @@ Typically bug fixes and new features start out as an idea or an experiment poste about things you want to implement. People proficient in certain areas of Scala usually monitor mailing lists, so you'll often get some help by simply posting a message. But the most efficient way to connect is to cc your message to one of the people responsible for maintaining the aspect of Scala which you wish to contribute to. -This is the list of language features/libraries along with their maintainers's full names and GitHub usernames: +This is the list of language features/libraries along with their maintainer's full names and GitHub usernames: {% include maintainers.html %} @@ -182,7 +182,7 @@ Here are also some tips & tricks that have proven useful in Scala development: just that trait, but it might also be necessary to recompile its users. The `ant` tool is not smart enough to do that, which might lead to very strange errors. Full-rebuilds fix the problem. Fortunately that's rarely necessary, because full-rebuilds take a lot of time-- the same 8-30 minutes as mentioned above. * Even on solid state drives packaging Scala distribution (i.e. creating jars from class files) is a non-trivial task. To save time here, - some people in our team do `ant quick.comp` instead of `ant` and then create custom scripts ([here](https://github.com/adriaanm/binfu/blob/master/scafu.sh) are some examples to get you strarted) to launch Scala from `build/quick/classes`. + some people in our team do `ant quick.comp` instead of `ant` and then create custom scripts ([here](https://github.com/adriaanm/binfu/blob/master/scafu.sh) are some examples to get you started) to launch Scala from `build/quick/classes`. * Don't underestimate the power of `print`. When starting with Scala, I spent a lot of time in the debugger trying to figure out how things work. However later I found out that print-based debugging is often more effective than jumping around. While it might be obvious to some, I'd like to explicitly mention that it's also useful to print stack traces to understand the flow of execution. When working with `Trees`, you might want to use `showRaw` to get the `AST` representation. @@ -415,6 +415,6 @@ workflow) and be ready to elaborate and adjust your patch if necessary. In this ## Merge -After your reviewer is happy with your code (usually signalled by a LGTM — “Looks good to me”), your job is done. +After your reviewer is happy with your code (usually signaled by a LGTM — “Looks good to me”), your job is done. Note that there can be a gap between a successful review and the merge, because not every reviewer has merge rights. In that case, someone else from the team will pick up your pull request and merge it. So don't be confused if your reviewer says “LGTM”, but your code doesn't get merged immediately. diff --git a/contribute/index.md b/contribute/index.md index 338ff06a06..433c579620 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -11,21 +11,56 @@ everyone make things better? ## How to help? -### Reporting bugs +That depends on what you want to contribute. Below are some getting started resources for different contribution domains. Please read all of the documentation and follow all the links from the topic pages below before attempting to contribute, as many of the questions you have will already be answered. -See our [bug reporting guide](./bug-reporting-guide.html) to learn -how to efficiently report a bug. +### Contribute -### Help with the documentation +Coordination of contribution efforts takes place on the +[scala-internals Google group](./scala-internals.html). -An easy but very important way to contribute to Scala is to -[help with the guide/tutorial-style documentation on docs.scala-lang.org](http://docs.scala-lang.org/contribute.html). -If you want to [contribute to Scala standard library API documentation](./scala-standard-library-api-documentation.html), the -process is slightly different, since API documentation lives within Scala standard library source code. +
+
+ +
+

Bug Fixes

+

Issues with the tools, core libraries and compiler. Also you can help us by reporting bugs

+
+
-### Compiler and other tools +
+
+

Tools

+

Enhance the Scala tooling ecosystem with features for build tools, IDE plug-ins and other related tools.

+
+
+

Core Libraries

+

Update and expand the capabilities of the core (and associated) Scala libraries.

+
+
+ +
+
+

Compiler/Language

+

Larger language features and compiler enhancements including language specification and SIPs.

+
+
+

Contributor Hall of Fame

+

Get your props, and find your place in the leader-board.

+
+
+
-More info in our [contributing guide](./guide.html). + +### Reporting bugs + +See our [bug reporting guide](./bug-reporting-guide.html) to learn +how to efficiently report a bug. ### Community Tickets @@ -35,33 +70,33 @@ various contributor activities:
-

Documentation

+

Documentation

Help augment or correct the documentation.

-

Core Libraries

+

Core Libraries

Community bugs and enhancements on the core libs.

-

Tools

+

Tools

Help with the Scala tool chain.

-

Compiler

+

Compiler

Ready for a challenge? Here's the compiler bugs.

-

Bugs

+

Bugs

All bugs marked with the label community.

-

All Issues

+

All Issues

Bugs + Enhancements marked with the label community.

diff --git a/contribute/scala-internals.md b/contribute/scala-internals.md new file mode 100644 index 0000000000..fa7faa9dc3 --- /dev/null +++ b/contribute/scala-internals.md @@ -0,0 +1,45 @@ +--- +layout: page +title: Scala Internals Mailing List +--- + +## scala-internals + +The [scala-internals mailing list](https://groups.google.com/d/forum/scala-internals) is where technical and logistical discussions concerning bugs, bug fixes, documentation, improvements, new features and other contributor related topics occur. + +### Coordinating on scala-internals + +Prior to commencing on contribution work for the Scala project, even for documentation and bugfixing, it is recommended (but not required) that you make a post on scala-internals announcing your intention. It's a great time to invite any help, advice or ask any questions you might have. It's also a great place to meet peers, one of whom will probably be reviewing your contribution at some point. + +To help subscribers on the scala-internals list to sort through the postings, we request that the following topic labels are applied when you start a new post please: + +| Label | Topics | +|-----------|-------------------------------------------------------| +| [docs] | Documentation, e.g. docs.scala-lang.org, API (scaladoc), etc. | +| [issues] | Bug reporting/fixing | +| [tools] | Tools including sbt, IDE plugins, testing, scaladoc generator, etc. | +| [libs] | Core libraries, extension libraries | +| [compiler] | Scala compiler discussions/features/issues | +| [admin] | Administrative/coordination topics | + +So, to talk about this list (an admin activity primarily) one might use: + +`[admin] more suggested labels for topic differentiation.` + +as a title, which then shows up on the mailing lists as + +`[scala-internals] [admin] more suggested labels for topic differentiation.` + +### Why It's a Good Idea + +While it is optional to announce your intentions/work items on scala-internals before starting, it is recommended and a smart thing to do for a number of reasons: + +* To attempt to cut down on duplicate effort (i.e. to avoid two people working on the same bug at the same time without coordinating effort). +* Related to the above: to allow the compiler team and core committers to warn of or smooth over potential merge conflicts between separate bugs that might affect the same code. +* Potentially someone has already thought about or even worked on that issue or a related one, and has valuable insight that might save you time (including warnings about what you might find and may want to avoid - dead ends that have already been explored). +* You might find a group of impassioned individuals want to volunteer to help you, since you got there first with your post it's up to you to decide if you want help or not. +* Posting could start a dialog with a potential reviewer, smoothing the latter, merge stages of the issue. +* There are a lot of nice people waiting to talk to you on scala-internals, you might be surprised how valuable and pleasant you find the experience of talking to them. + +If all of this has not convinced you then, please, go ahead and work on contributions anyway. It *is* less important to post to scala-internals first for small, self contained bugs than it is for larger issues or features, and not having posted first will not be a reason for your PR to be rejected, it just might be a rougher review/merge process than if you had posted first. It's your choice. + diff --git a/contribute/scala-standard-library-api-documentation.md b/contribute/scala-standard-library-api-documentation.md index 519c85a030..14eb55845c 100644 --- a/contribute/scala-standard-library-api-documentation.md +++ b/contribute/scala-standard-library-api-documentation.md @@ -72,7 +72,7 @@ component so that they show up in the correct issue filters. ### Required Reading -Please familiarize yourself with **all** of the following before contributing +Please familiarize yourself with the following before contributing new API documentation to save time, effort, mistakes and repetition. * [Forking the Repo](./hacker-guide.html#2_set_up) - follow the setup steps through @@ -86,7 +86,7 @@ new API documentation to save time, effort, mistakes and repetition. companions, browsing package object documentation, searching, token searches and so on. * Prior to commit, be sure to read - [A note about git commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). + [A note about git commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) and the [Scala Project & Developer Guidelines](https://github.com/scala/scala/blob/2.11.x/CONTRIBUTING.md). * Also read the Scala [Pull Request Policy](https://github.com/scala/scala/wiki/Pull-Request-Policy). Some of this document will clearly not apply (like the sections on providing tests, however see below for some special requirements for documentation). Do still read @@ -95,7 +95,7 @@ new API documentation to save time, effort, mistakes and repetition. cleanly. Remember that the title of the pull request will become the commit message when merged. **Also**, be sure to assign one or more reviewers to the PR, list of reviewers is at the bottom of this document, but the quick version is to add - `Review by @dickwall` **in the pull request comments**. + `Review by @heathermiller` or `Review by @dickwall` **in the pull request comments**. ### Extra Requirements for Scaladoc Documentation Commits diff --git a/contribute/tools.md b/contribute/tools.md new file mode 100644 index 0000000000..4378d6f568 --- /dev/null +++ b/contribute/tools.md @@ -0,0 +1,8 @@ +--- +layout: page +title: Tool Contributions +--- +## Under Construction + +If you would like to help complete this document, welcome, and please head over and read [Documentation Contributions](./documentation.html#the-scala-language-site), +and let us know on the [scala-internals](https://groups.google.com/forum/#!forum/scala-internals) forum (suggested post title: `[docs] Tool Contributions`) so that we can get you hooked up with the right people. \ No newline at end of file From 0083e203436a2f64c8d50029b93cda39bba5c125 Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Tue, 10 Feb 2015 12:01:59 -0800 Subject: [PATCH 0061/3075] Alter when documentation/bug fix scala-internals postings are recommended. --- contribute/scala-internals.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/scala-internals.md b/contribute/scala-internals.md index fa7faa9dc3..5bd97ed8a8 100644 --- a/contribute/scala-internals.md +++ b/contribute/scala-internals.md @@ -9,7 +9,7 @@ The [scala-internals mailing list](https://groups.google.com/d/forum/scala-inter ### Coordinating on scala-internals -Prior to commencing on contribution work for the Scala project, even for documentation and bugfixing, it is recommended (but not required) that you make a post on scala-internals announcing your intention. It's a great time to invite any help, advice or ask any questions you might have. It's also a great place to meet peers, one of whom will probably be reviewing your contribution at some point. +Prior to commencing on contribution work on larger changes to the Scala project, it is recommended (but not required) that you make a post on scala-internals announcing your intention. It's a great time to invite any help, advice or ask any questions you might have. It's also a great place to meet peers, one of whom will probably be reviewing your contribution at some point. For smaller bug fixes or documentation changes where the risk of effort duplication is minimal, you can skip this post. To help subscribers on the scala-internals list to sort through the postings, we request that the following topic labels are applied when you start a new post please: From d7c254b48255eda00420e38d1273e46e88213bc3 Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Tue, 10 Feb 2015 13:50:21 -0800 Subject: [PATCH 0062/3075] Correct scala-internals link and remove missing resource links. --- contribute/guide.md | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/contribute/guide.md b/contribute/guide.md index 809c6558d5..90f16082d6 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -54,7 +54,7 @@ This is the impatient developer's checklist for the steps to submit a bug-fix pu 1. [Select a bug to fix from JIRA](https://issues.scala-lang.org/issues/?filter=12111), or if you found the bug yourself and want to fix it, [create a JIRA issue](./bug-reporting-guide.html) (but please [make sure it's not a duplicate](./bug-reporting-guide.html#reporting-confirmed-bugs-is-a-sin)). -2. Optional ([but recommended](./scala-internals#why-its-a-good-idea)), announce your intention to work on the bug on [scala-internals](./scala-internals.html). After all, don't you want to work on a team with +2. Optional ([but recommended](./scala-internals.html#why-its-a-good-idea)), announce your intention to work on the bug on [scala-internals](./scala-internals.html). After all, don't you want to work on a team with [these friendly people](./hacker-guide.html#connect) - it's one of the perks of contributing. 3. [Fork the Scala repository](./hacker-guide.html#fork) and clone your fork (if you haven't already). 4. [Create a feature branch](./hacker-guide.html#branch) to work on: use the branch name `issue/NNNN` where NNNN is the JIRA issue number. @@ -78,19 +78,3 @@ on the [scala-internals](http://groups.google.com/group/scala-internals) mailing Contributions, big or small, simple or complex, controversial or undisputed, need to materialize as patches against the Scala project source tree. The [hacker guide](hacker-guide.html) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. -### Further Reading for Larger Changes - -The files below are recordings of code walk-through sessions by Martin Odersky about the Scala compiler internals. Some of the information is somewhat outdated, but the clips are still a good introduction to some parts of the compiler architecture. - - - [Scala Internals 2008-10-29 (Symbols 1)](http://www.scala-lang.org/sites/default/files/martin_ordersky_scala_internals_2008-10-29.avi) - - Handling of Symbols in the Scala compiler: some details on the symtab subdir, Symbols, Definitions, StdNames, Types (Lazy Types). - - - [Scala Internals 2008-11-05 (Symbols 2)](http://www.scala-lang.org/sites/default/files/martin_ordersky_scala_internals_2008-11-05.avi) - - Handling of Symbols part deux: more information on Symbols, Flags, Definitions. - - - [Scala Internals 2009-03-04 (Types)](http://www.scala-lang.org/sites/default/files/martin_ordersky_scala_internals_2009-03-04.avi) - - A detailed explanation about how types are represented and manipulated within the Scala compiler: data structures, manipulations of types, coding conventions (audio is not perfect, but intelligible). - From a4fb06f631262af3f87b6efd14d5078ac992c761 Mon Sep 17 00:00:00 2001 From: Fabien Salvi Date: Mon, 16 Feb 2015 09:55:48 +0100 Subject: [PATCH 0063/3075] Add scala-fame data --- .../_posts/2015-02-01-scala-fame-2015-01.md | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 contribute/scala-fame-data/_posts/2015-02-01-scala-fame-2015-01.md diff --git a/contribute/scala-fame-data/_posts/2015-02-01-scala-fame-2015-01.md b/contribute/scala-fame-data/_posts/2015-02-01-scala-fame-2015-01.md new file mode 100644 index 0000000000..4af6e3d778 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2015-02-01-scala-fame-2015-01.md @@ -0,0 +1,56 @@ +--- +layout: famearchive +title: Contributors of January 2015 +fame-year: 2015 +fame-month: 1 +fame-month-str: January +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://avatars1.githubusercontent.com/u/65551?v=3&s=60 + commits: 10 + linesAdded: 222 + linesDeleted: 26 + rank: 1 + newContributor: false + - username: adriaanm + gravatar: https://avatars3.githubusercontent.com/u/91083?v=3&s=60 + commits: 4 + linesAdded: 819 + linesDeleted: 636 + rank: 2 + newContributor: false + - category: EPFL + authors: + - username: lrytz + gravatar: https://avatars2.githubusercontent.com/u/119636?v=3&s=60 + commits: 4 + linesAdded: 470 + linesDeleted: 152 + rank: 1 + newContributor: false + - category: Community + authors: + - username: kanielc + gravatar: https://avatars1.githubusercontent.com/u/1334074?v=3&s=60 + commits: 2 + linesAdded: 58 + linesDeleted: 2 + rank: 1 + newContributor: false + - username: som-snytt + gravatar: https://avatars3.githubusercontent.com/u/369425?v=3&s=60 + commits: 2 + linesAdded: 35 + linesDeleted: 41 + rank: 1 + newContributor: false + - username: dickwall + gravatar: https://avatars2.githubusercontent.com/u/56453?v=3&s=60 + commits: 1 + linesAdded: 74 + linesDeleted: 0 + rank: 2 + newContributor: false +--- From db78065ef0defcd7b863409625974509c687ba3a Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Tue, 17 Feb 2015 11:50:40 -0800 Subject: [PATCH 0064/3075] Re-org and simplify contribution section pages. * Removed hall of fame links (as the feature is being removed) * Temporarily disabled tools page link until we work out what to do for tools * Shuffled documentation contrib order to emphasize scaladoc over activator --- contribute/documentation.md | 16 ++++++++-------- contribute/guide.md | 2 +- contribute/index.md | 32 +++++++++++++------------------- 3 files changed, 22 insertions(+), 28 deletions(-) diff --git a/contribute/documentation.md b/contribute/documentation.md index da20b9360d..cb2f7a46fb 100644 --- a/contribute/documentation.md +++ b/contribute/documentation.md @@ -6,9 +6,9 @@ title: Documentation Contributions There are several ways you can help out with the improvement of Scala documentation. These include: +* API Documentation in Scaladoc * Code examples and tutorials in activator templates. * The Scala Wiki -* API Documentation in Scaladoc * Guides, Overviews, Tutorials, Cheat Sheets and more on the docs.scala-lang.org site * Updating Documents on the Main Scala Language Site (this one) @@ -18,13 +18,6 @@ Please read this page, and the pages linked from this one, fully before contribu Thanks -### Examples/Tutorials in Activator Templates - -[Typesafe Activator](https://typesafe.com/community/core-tools/activator-and-sbt) -is a tool based on SBT, with a UI mode that is ideal for code based tutorials, overviews and walk-throughs. To contribute an example in activator, you can fork an existing template, edit it, add a tutorial, upload it to github and then submit the github project into the template repository. It's the fastest way to produce a working code example with tutorial. - -Please see [Contributing an Activator Template](https://typesafe.com/activator/template/contribute) for more details. - ### API Documentation (Scaladoc) The Scala API documentation lives with the scala project source code. There are many ways you can help with improving Scaladoc, including: @@ -36,6 +29,13 @@ Please *follow the issue submission process closely* to help prevent duplicate i [submit new Scaladoc](./scala-standard-library-api-documentation.html) without creating an issue, but please look to see if there is an issue already submitted for your task and claim it if there is. If not, please post your intention to work on a specific scaladoc task on scala-internals so that people know what you are doing. +### Examples/Tutorials in Activator Templates + +[Typesafe Activator](https://typesafe.com/community/core-tools/activator-and-sbt) +is a tool based on SBT, with a UI mode that is ideal for code based tutorials, overviews and walk-throughs. To contribute an example in activator, you can fork an existing template, edit it, add a tutorial, upload it to github and then submit the github project into the template repository. It's the fastest way to produce a working code example with tutorial. + +Please see [Contributing an Activator Template](https://typesafe.com/activator/template/contribute) for more details. + ### The Scala Wiki The [Scala wiki](https://wiki.scala-lang.org/) could be a useful resource, but tends to get out of date quickly. It is perhaps best viewed as a place for information to temporarily live while it is constructed and refined, but with an aim to putting the material into the [docs.scala-lang.org](http://docs.scala-lang.org) site eventually (see the next section). Nonetheless, it is a fast way to add some public documentation. diff --git a/contribute/guide.md b/contribute/guide.md index 90f16082d6..bf323c39e5 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -65,7 +65,7 @@ This is the impatient developer's checklist for the steps to submit a bug-fix pu https://github.com/scala/scala#git-hygiene). For bug fixes, a single commit is requested, for features several commits may be desirable (but each separate commit must compile and pass all tests) 9. [Submit a pull request](./hacker-guide.html#submit) following the [Scala project pull-request guidelines](http://docs.scala-lang.org/scala/pull-request-policy.html). 10. [Work with a reviewer](https://github.com/scala/scala#reviewing) to [get your pull request merged in](./hacker-guide.html#review). -11. [Bask in the glow of a job well done](./scala-fame.html). +11. Celebrate! Need more information or a little more hand-holding for the first one? We got you covered: take a read through the entire [Hacker Guide](./hacker-guide.html) for an example of implementing a new feature (some of the steps can be skipped for bug fixes, this will be obvious from reading it, but many of the steps here will help with bug fixes too). diff --git a/contribute/index.md b/contribute/index.md index 433c579620..405a675ea6 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -13,6 +13,11 @@ everyone make things better? That depends on what you want to contribute. Below are some getting started resources for different contribution domains. Please read all of the documentation and follow all the links from the topic pages below before attempting to contribute, as many of the questions you have will already be answered. +### Reporting bugs + +See our [bug reporting guide](./bug-reporting-guide.html) to learn +how to efficiently report a bug. + ### Contribute Coordination of contribution efforts takes place on the @@ -22,8 +27,7 @@ Coordination of contribution efforts takes place on the
@@ -35,33 +39,23 @@ Coordination of contribution efforts takes place on the
-

Tools

-

Enhance the Scala tooling ecosystem with features for build tools, IDE plug-ins and other related tools.

-
-

Core Libraries

Update and expand the capabilities of the core (and associated) Scala libraries.

-
- -
-

Compiler/Language

+

Compiler/Language

Larger language features and compiler enhancements including language specification and SIPs.

-
-

Contributor Hall of Fame

-

Get your props, and find your place in the leader-board.

+ +
- -### Reporting bugs - -See our [bug reporting guide](./bug-reporting-guide.html) to learn -how to efficiently report a bug. - ### Community Tickets The following links provide starting points for From 090c9de45ab7a8c810469853699292aafe0ca865 Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Tue, 17 Feb 2015 13:19:18 -0800 Subject: [PATCH 0065/3075] Remove wiki info, use scala-lang.org. --- contribute/documentation.md | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/contribute/documentation.md b/contribute/documentation.md index cb2f7a46fb..81ebba7b3f 100644 --- a/contribute/documentation.md +++ b/contribute/documentation.md @@ -8,9 +8,8 @@ There are several ways you can help out with the improvement of Scala documentat * API Documentation in Scaladoc * Code examples and tutorials in activator templates. -* The Scala Wiki * Guides, Overviews, Tutorials, Cheat Sheets and more on the docs.scala-lang.org site -* Updating Documents on the Main Scala Language Site (this one) +* Updating scala-lang.org Please read this page, and the pages linked from this one, fully before contributing documentation. Many of the questions you have will be answered in these resources. If you have a question that isn't answered, feel free to ask on the [scala-internals Google group](https://groups.google.com/forum/#!forum/scala-internals) and then, please, submit a pull request with updated documentation reflecting that answer. @@ -36,12 +35,6 @@ is a tool based on SBT, with a UI mode that is ideal for code based tutorials, o Please see [Contributing an Activator Template](https://typesafe.com/activator/template/contribute) for more details. -### The Scala Wiki - -The [Scala wiki](https://wiki.scala-lang.org/) could be a useful resource, but tends to get out of date quickly. It is perhaps best viewed as a place for information to temporarily live while it is constructed and refined, but with an aim to putting the material into the [docs.scala-lang.org](http://docs.scala-lang.org) site eventually (see the next section). Nonetheless, it is a fast way to add some public documentation. - -The wiki is self documenting, so make sure to take a look at the [home page](https://wiki.scala-lang.org/) to get started. Please consider contributions to [docs.scala-lang.org](docs.scala-lang.org) for more enduring documentation, even though it is more work to get through the review process for the main doc site. - ### The Main Scala Documentation Site [docs.scala-lang.org](https://wiki.scala-lang.org/) houses the primary source of written, non-API documentation for Scala. It's a github project that you can fork and submit pull requests from. It includes: @@ -59,7 +52,7 @@ and more Please read [contributing to the docs.scala-lang.org site](http://docs.scala-lang.org/contribute.html) through before embarking on changes. The site uses the [Jekyll](http://jekyllrb.com/) markdown engine so you will need to follow the instructions to get that running as well. -### The Scala Language Site +### Updating scala-lang.org Additional high-level documentation (including documentation on contributing to Scala and related projects) is provided on the main From e172523885936286894c661fc450ff3378135dd5 Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Wed, 18 Feb 2015 14:46:54 -0800 Subject: [PATCH 0066/3075] Add IDEs and Build Tools page * IDEs and Build Tools page consists of links out to important scala projects * Restored link to above page, and renamed to IDEs and Build Tools * Added a missing link into the documentation.md page --- contribute/documentation.md | 2 +- contribute/index.md | 12 ++-- contribute/tools.md | 123 ++++++++++++++++++++++++++++++++++-- 3 files changed, 126 insertions(+), 11 deletions(-) diff --git a/contribute/documentation.md b/contribute/documentation.md index 81ebba7b3f..c4704eee0b 100644 --- a/contribute/documentation.md +++ b/contribute/documentation.md @@ -60,5 +60,5 @@ to Scala and related projects) is provided on the main [scala-lang github project](https://github.com/scala/scala-lang) which may be forked to create pull requests. Please read both the -[docs.scala-lang.org contribution](http://docs.scala-lang.org/contribute.html) document and the scala-lang.org github README file before embarking on any changes to the Scala language site, as it uses the same Jekyll markdown tool and many of the same conventions as the Scala documentation site. +[docs.scala-lang.org contribution](http://docs.scala-lang.org/contribute.html) document and the [scala-lang.org github README](https://github.com/dickwall/scala-lang#scala-langorg) before embarking on any changes to the Scala language site, as it uses the same Jekyll markdown tool and many of the same conventions as the Scala documentation site. diff --git a/contribute/index.md b/contribute/index.md index 405a675ea6..2d98744a6f 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -43,17 +43,17 @@ Coordination of contribution efforts takes place on the

Update and expand the capabilities of the core (and associated) Scala libraries.

-

Compiler/Language

-

Larger language features and compiler enhancements including language specification and SIPs.

+

IDE and Build Tools

+

Enhance the Scala tools with features for build tools, IDE plug-ins and other related projects.

- ### Community Tickets diff --git a/contribute/tools.md b/contribute/tools.md index 4378d6f568..53b097a696 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -1,8 +1,123 @@ --- layout: page -title: Tool Contributions +title: IDE and Build Tool Contributions --- -## Under Construction +## Contributing to IDE and Build Tools -If you would like to help complete this document, welcome, and please head over and read [Documentation Contributions](./documentation.html#the-scala-language-site), -and let us know on the [scala-internals](https://groups.google.com/forum/#!forum/scala-internals) forum (suggested post title: `[docs] Tool Contributions`) so that we can get you hooked up with the right people. \ No newline at end of file +The links below are to a number of Scala build and IDE related projects that are important in the larger Scala space, and which welcome contributions. + +Since these tools are in separate projects, they may (and likely will) have their own rules and guidelines for contributing. The [Hacker Guide](./hacker-guide.html) and [Bug-fixing](guide.html) pages will likely have much in the way of related information on how to contribute to these projects, and are recommended reading. You should also check the README.md and (if it's present) CONTRIBUTING.md files from the actual projects before contributing to them. + +Typically, issues for these projects will be reported and kept in the github project issue tracker for that project rather than in the Scala project JIRA. +Many of these projects have a gitter channel (usually listed in the README or CONTRIBUTING documents) which is a great place to discuss proposed work before commencing. + +### Broken Links? + +Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](./documentation.html#updating-scala-langorg) to fix it. + +### Projects + +
+
+
+

Scala IDE

+

The Eclipse Scala IDE project.

+

Home | +Issues | +ReadMe | +Contributing

+
+
+ +

sbt

+

Interactive build tool.

+

Home | +Issues | +ReadMe | +Contributing

+
+
+ +
+
+ +

Scaladoc Tool

+

(Contribute through scala/scala)

+

Home | +Issues | +ReadMe | +Contributing

+
+
+

DBuild

+

Multi-project build tool.

+

Home | +Issues | +ReadMe | +Contributing

+
+
+ +
+
+

Ensime

+

Scala Support for Text Editors

+

Home | +Issues | +ReadMe | +Contributing

+
+
+ +

Abide

+

Lint tooling for Scala

+

Home | +Issues | +ReadMe | +Contributing

+
+
+ +
+
+ +

Partest

+

Scala Compiler/Library Testing

+

Home | +Issues | +ReadMe

+
+
+

Scoverage

+

Scala code coverage tool

+

Home | +Issues | +ReadMe | +Contributing

+
+
+
+ +### Projects in Particular Need + +The following projects are important to the Scala community but are particularly in need of contributors to continue their development. + +
+
+
+ +

Scalap

+

Scala Decoder (part of scala/scala)

+Issues | +ReadMe | +Contributing

+
+
+

Scalariform

+

Scala code formatter

+

Home | +Issues | +ReadMe

+
+
+
From 391caec69a325cdac6c1531a717bc21cc001605d Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Tue, 10 Mar 2015 10:16:07 -0700 Subject: [PATCH 0067/3075] Respond to review comments - correct link, reorder projects * Re-order the projects in approximate order of importance * Corrected scala docs link to correct github project --- contribute/documentation.md | 2 +- contribute/tools.md | 60 ++++++++++++++++++++----------------- 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/contribute/documentation.md b/contribute/documentation.md index c4704eee0b..c0de56d9b1 100644 --- a/contribute/documentation.md +++ b/contribute/documentation.md @@ -60,5 +60,5 @@ to Scala and related projects) is provided on the main [scala-lang github project](https://github.com/scala/scala-lang) which may be forked to create pull requests. Please read both the -[docs.scala-lang.org contribution](http://docs.scala-lang.org/contribute.html) document and the [scala-lang.org github README](https://github.com/dickwall/scala-lang#scala-langorg) before embarking on any changes to the Scala language site, as it uses the same Jekyll markdown tool and many of the same conventions as the Scala documentation site. +[docs.scala-lang.org contribution](http://docs.scala-lang.org/contribute.html) document and the [scala-lang.org github README](https://github.com/scala/scala-lang#scala-langorg) before embarking on any changes to the Scala language site, as it uses the same Jekyll markdown tool and many of the same conventions as the Scala documentation site. diff --git a/contribute/tools.md b/contribute/tools.md index 53b097a696..dab8244d0f 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -11,6 +11,10 @@ Since these tools are in separate projects, they may (and likely will) have thei Typically, issues for these projects will be reported and kept in the github project issue tracker for that project rather than in the Scala project JIRA. Many of these projects have a gitter channel (usually listed in the README or CONTRIBUTING documents) which is a great place to discuss proposed work before commencing. +There are some projects in this section that are in +[particular need](#projects-in-particular-need) so please check those out +if you would like to help revive them. + ### Broken Links? Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](./documentation.html#updating-scala-langorg) to fix it. @@ -20,14 +24,6 @@ Stuff changes. Found a broken link or something that needs updating on this page
-

Scala IDE

-

The Eclipse Scala IDE project.

-

Home | -Issues | -ReadMe | -Contributing

-
-

sbt

Interactive build tool.

@@ -36,9 +32,6 @@ Stuff changes. Found a broken link or something that needs updating on this page ReadMe | Contributing

-
- -

Scaladoc Tool

@@ -48,6 +41,17 @@ Stuff changes. Found a broken link or something that needs updating on this page ReadMe | Contributing

+
+ +
+
+

Scala IDE

+

The Eclipse Scala IDE project.

+

Home | +Issues | +ReadMe | +Contributing

+

DBuild

Multi-project build tool.

@@ -60,6 +64,14 @@ Stuff changes. Found a broken link or something that needs updating on this page
+ +

Partest

+

Scala Compiler/Library Testing

+

Home | +Issues | +ReadMe

+
+

Ensime

Scala Support for Text Editors

Home | @@ -67,27 +79,10 @@ Stuff changes. Found a broken link or something that needs updating on this page ReadMe | Contributing

-
- -

Abide

-

Lint tooling for Scala

-

Home | -Issues | -ReadMe | -Contributing

-
- -

Partest

-

Scala Compiler/Library Testing

-

Home | -Issues | -ReadMe

-
-

Scoverage

Scala code coverage tool

Home | @@ -95,6 +90,15 @@ Stuff changes. Found a broken link or something that needs updating on this page ReadMe | Contributing

+
+ +

Abide

+

Lint tooling for Scala

+

Home | +Issues | +ReadMe | +Contributing

+
From 78759cd80f9a25baef7d9b437b829a8ac66261c4 Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Wed, 11 Mar 2015 09:44:19 -0700 Subject: [PATCH 0068/3075] Tweak the all community bugs link * No longer sort by component - sort by votes instead. --- contribute/guide.md | 2 +- contribute/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contribute/guide.md b/contribute/guide.md index bf323c39e5..8c07448ba7 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -52,7 +52,7 @@ unencumbered by copyrights or patents. This is the impatient developer's checklist for the steps to submit a bug-fix pull request to the Scala project. For more information, description and justification for the steps, follow the links in that step. Further specific instructions for the release of Scala you are targeting can be found in the `CONTRIBUTING.md` file for that [github branch](https://github.com/scala/scala) -1. [Select a bug to fix from JIRA](https://issues.scala-lang.org/issues/?filter=12111), or if you found the bug yourself and want to fix it, [create a JIRA issue](./bug-reporting-guide.html) (but please +1. [Select a bug to fix from JIRA](/contribute/#community-tickets), or if you found the bug yourself and want to fix it, [create a JIRA issue](./bug-reporting-guide.html) (but please [make sure it's not a duplicate](./bug-reporting-guide.html#reporting-confirmed-bugs-is-a-sin)). 2. Optional ([but recommended](./scala-internals.html#why-its-a-good-idea)), announce your intention to work on the bug on [scala-internals](./scala-internals.html). After all, don't you want to work on a team with [these friendly people](./hacker-guide.html#connect) - it's one of the perks of contributing. diff --git a/contribute/index.md b/contribute/index.md index 2d98744a6f..0a37b87a73 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -90,7 +90,7 @@ various contributor activities:

All bugs marked with the label community.

-

All Issues

+

All Issues

Bugs + Enhancements marked with the label community.

From 84da163c3d36575459983b9d2d59fba25dfbea10 Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Tue, 17 Mar 2015 13:28:27 -0700 Subject: [PATCH 0069/3075] Add fix me links and core lib page. * Add a fix this page link under contents list * Create a simple landing page for core libs - direct to docs.scala.lang --- contribute/corelibs.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/contribute/corelibs.md b/contribute/corelibs.md index 1429ec87ff..6e1abbb0d7 100644 --- a/contribute/corelibs.md +++ b/contribute/corelibs.md @@ -2,7 +2,20 @@ layout: page title: Core Library Contributions --- -## Under Construction +## Core Library Contributions -If you would like to help complete this document, welcome, and please head over and read [Documentation Contributions](./documentation.html#the-scala-language-site), -and let us know on the [scala-internals](https://groups.google.com/forum/#!forum/scala-internals) forum (suggested post title: `[docs] Core Library Contributions`) so that we can get you hooked up with the right people. \ No newline at end of file +There are several options for contributing to Scala's core libraries. You can: + +* Help with [Documentation](./scala-standard-library-api-documentation.html). +* [Report Bugs or Issues](./bug-reporting-guide.html) against the core libraries. +* [Fix Bugs or Issues](./guide.html) against the + [reported library bugs/issues](https://issues.scala-lang.org/issues/?filter=13001). +* Contribute significant new functionality or a new API by submitting + a Scala Library Improvement Process (SLIP) Document. + +### Submitting a SLIP + +For significant new functionality or a whole new API to be considered for +inclusion in the core Scala distribution, you will be asked to submit a SLIP (Scala Library Improvement Process) document. + +Please see [instructions for submitting a new SLIP](http://docs.scala-lang.org/sips/slip-submission.html) and familiarize yourself with the [SIP/SLIP](http://docs.scala-lang.org/sips/) section of the Scala documentation site. Also please pay particular attention to the [pre-requisites](http://docs.scala-lang.org/sips/slip-submission.html) before submitting a SLIP. From 66c5272ca07370c7c6448a30c24da2c66455dcd0 Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Tue, 17 Mar 2015 13:54:39 -0700 Subject: [PATCH 0070/3075] Add a missing paragraph opener on tools.md --- contribute/tools.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/contribute/tools.md b/contribute/tools.md index dab8244d0f..023c638082 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -112,7 +112,7 @@ The following projects are important to the Scala community but are particularly

Scalap

Scala Decoder (part of scala/scala)

-Issues | +

Issues | ReadMe | Contributing

@@ -125,3 +125,5 @@ The following projects are important to the Scala community but are particularly + + \ No newline at end of file From cde252c3e88bdb803f48c4bf30e33c8ffe6da1de Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Tue, 17 Mar 2015 14:50:34 -0700 Subject: [PATCH 0071/3075] Fix intra-page links for main markdown engine. * Local jekyll uses - but main site uses _ for intra-page anchors --- contribute/guide.md | 8 ++++---- contribute/index.md | 2 +- contribute/tools.md | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contribute/guide.md b/contribute/guide.md index 8c07448ba7..04fe50ae5b 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -17,7 +17,7 @@ title: Contributing guide
-

Community issues

+

Community issues

Get cracking on some easy to approach issues.

@@ -52,9 +52,9 @@ unencumbered by copyrights or patents. This is the impatient developer's checklist for the steps to submit a bug-fix pull request to the Scala project. For more information, description and justification for the steps, follow the links in that step. Further specific instructions for the release of Scala you are targeting can be found in the `CONTRIBUTING.md` file for that [github branch](https://github.com/scala/scala) -1. [Select a bug to fix from JIRA](/contribute/#community-tickets), or if you found the bug yourself and want to fix it, [create a JIRA issue](./bug-reporting-guide.html) (but please -[make sure it's not a duplicate](./bug-reporting-guide.html#reporting-confirmed-bugs-is-a-sin)). -2. Optional ([but recommended](./scala-internals.html#why-its-a-good-idea)), announce your intention to work on the bug on [scala-internals](./scala-internals.html). After all, don't you want to work on a team with +1. [Select a bug to fix from JIRA](/contribute/index.html#community_tickets), or if you found the bug yourself and want to fix it, [create a JIRA issue](./bug-reporting-guide.html) (but please +[make sure it's not a duplicate](./bug-reporting-guide.html#reporting_confirmed_bugs_is_a_sin)). +2. Optional ([but recommended](./scala-internals.html#why_its_a_good_idea)), announce your intention to work on the bug on [scala-internals](./scala-internals.html). After all, don't you want to work on a team with [these friendly people](./hacker-guide.html#connect) - it's one of the perks of contributing. 3. [Fork the Scala repository](./hacker-guide.html#fork) and clone your fork (if you haven't already). 4. [Create a feature branch](./hacker-guide.html#branch) to work on: use the branch name `issue/NNNN` where NNNN is the JIRA issue number. diff --git a/contribute/index.md b/contribute/index.md index 0a37b87a73..a272a8b98d 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -50,7 +50,7 @@ Coordination of contribution efforts takes place on the
-

Compiler/Language

+

Compiler/Language

Larger language features and compiler enhancements including language specification and SIPs.

diff --git a/contribute/tools.md b/contribute/tools.md index 023c638082..92207f4da2 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -12,12 +12,12 @@ Typically, issues for these projects will be reported and kept in the github pro Many of these projects have a gitter channel (usually listed in the README or CONTRIBUTING documents) which is a great place to discuss proposed work before commencing. There are some projects in this section that are in -[particular need](#projects-in-particular-need) so please check those out +[particular need](#projects_in_particular_need) so please check those out if you would like to help revive them. ### Broken Links? -Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](./documentation.html#updating-scala-langorg) to fix it. +Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](./documentation.html#updating_scala_langorg) to fix it. ### Projects From 70673bb169853d0caf796d63e4aa3030238f1ba1 Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Tue, 17 Mar 2015 15:01:50 -0700 Subject: [PATCH 0072/3075] Remove extra _ in fix-page link. --- contribute/tools.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/tools.md b/contribute/tools.md index 92207f4da2..1757ae1005 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -17,7 +17,7 @@ if you would like to help revive them. ### Broken Links? -Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](./documentation.html#updating_scala_langorg) to fix it. +Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](./documentation.html#updating_scalalangorg) to fix it. ### Projects From fa3402a41320cbfb6c0ba3c3f4970e8633e5b596 Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Tue, 17 Mar 2015 15:20:28 -0700 Subject: [PATCH 0073/3075] Fix documentation page intra-link. --- contribute/documentation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/documentation.md b/contribute/documentation.md index c0de56d9b1..d7597d8884 100644 --- a/contribute/documentation.md +++ b/contribute/documentation.md @@ -21,7 +21,7 @@ Thanks The Scala API documentation lives with the scala project source code. There are many ways you can help with improving Scaladoc, including: -* [Log issues for missing scaladoc documentation](./scala-standard-library-api-documentation.html#contribute-api-documentation-bug-reports) - +* [Log issues for missing scaladoc documentation](./scala-standard-library-api-documentation.html#contribute_api_documentation_bug_reports) - Please *follow the issue submission process closely* to help prevent duplicate issues being created. * [Claim Scaladoc Issues and Provide Documentation](./scala-standard-library-api-documentation.html) - please claim issues prior to working on a specific scaladoc task to prevent duplication of effort. If you sit on an issue for too long without submitting a pull request, it will revert back to unassigned and you will need to re-claim it. * You can also just From fc02b4d49bcc4d85f59fa0f1d1df913b2e102521 Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Mon, 23 Mar 2015 15:22:16 -0700 Subject: [PATCH 0074/3075] Add contribute PR review page to /contribute * Pull request reviewing was overlooked in recent contribute changes --- contribute/codereviews.md | 60 +++++++++++++++++++++++++++++++++++++++ contribute/index.md | 12 ++++++-- 2 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 contribute/codereviews.md diff --git a/contribute/codereviews.md b/contribute/codereviews.md new file mode 100644 index 0000000000..87ab392f1c --- /dev/null +++ b/contribute/codereviews.md @@ -0,0 +1,60 @@ +--- +layout: page +title: Code Review Contributions +--- +## Code Review Contributions + +In addition to [bug fixing](./guide.html), you can help us review +[waiting pull requests](#pull_requests_awaiting_comment). This is also a good (and recommended) way to get to know the feel of +the bug-fixing and submissions process before jumping in (lurk for a while, +reading pull requests from others and maybe commenting on them). + +### Etiquette + +[Code of Conduct Reminder](http://docs.scala-lang.org/conduct.html) + +There are many coding approaches and styles. Asserting that yours is the only correct one is not likely to lead to a smooth interaction with others. Code review is where programmers (often volunteers) surrender up their efforts for public scrutiny. + +Code reviewing is a great way to both learn and mentor, and *all* comments made during pull request reviews should bear those two aims in mind. + +Assuming the pull request has been made following the guidelines laid out in the rest of the contributor documentation (e.g. for Scala bug fixes, the PR is against an open issue, and has adhered to the guidelines for code changes and submitting the PR), then the comments for the pull request are *not* the correct place to discuss on whether this PR is even needed or other broad, negative assertions. + +The comments are for looking for potential problems in the code, suggesting improvements, looking for items that might have been missed by the submitter and so on. If you feel it necessary to discuss whether the issue should even be addressed, that should be carried out ([in a professional manner](http://docs.scala-lang.org/conduct.html)) on the comments for that Issue rather than the PR. General discussions should likewise be directed to forums like [scala-debate](https://groups.google.com/d/forum/scala-debate), [scala-user](https://groups.google.com/d/forum/scala-user), [scala-language](https://groups.google.com/d/forum/scala-language) or [scala-internals](https://groups.google.com/d/forum/scala-internals). + +Conversely if you are receiving a review, consider that the advice is being given to make you, and Scala, better rather than as a negative critique. Assume the best, rather than the worst. + +### Review Guidelines + +* Keep comments on-topic, concise and precise. +* Attach comments to particular lines or regions they pertain to whenever possible. +* Short code examples are often more descriptive than prose. +* If (and only if) you have thoroughly reviewed the PR and thought through all angles, and you want to accept it, LGTM (Looks Good To Me) is the preferred acceptance response. If there are already LGTMs on the PR, consider whether you are adding anything or just being "me too". +* Above all, remember that the people you are reviewing might be reviewing your PRs one day too :-). + +## Pull Requests Awaiting Comment + +
+
+
+

scala/scala

+

Scala bug fixes and changes in the language, core libs and included tools.

+
+
+

scala/github.scala.com

+

Scala documentation site.

+
+
+ +
+
+

scala/scala-lang

+

The Scala language web site.

+
+
+

All Scala Github Projects

+

For other PRs, follow the scala project from here.

+
+
+
+ +Also note that the [Tools contributions](./tools.html) page has more projects that will generate pull requests. \ No newline at end of file diff --git a/contribute/index.md b/contribute/index.md index a272a8b98d..fd94af5de2 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -39,16 +39,22 @@ Coordination of contribution efforts takes place on the
+

Code Reviews

+

Review pull requests against scala/scala, +scala/scala-lang, +scala/scala.github.com and others.

+
+

Core Libraries

Update and expand the capabilities of the core (and associated) Scala libraries.

+
+ +

IDE and Build Tools

Enhance the Scala tools with features for build tools, IDE plug-ins and other related projects.

-
- -

Compiler/Language

Larger language features and compiler enhancements including language specification and SIPs.

From 77cd3f5f78cb9ed89311ff2f5a811b6e25cf52c1 Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Tue, 24 Mar 2015 14:07:31 -0700 Subject: [PATCH 0075/3075] Incorporate comments, reduce wordiness * Cut etiquette section * Include Code of Conduct link in Review Guidelines section * Change wording aroung LGTM and additional reviews --- contribute/codereviews.md | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/contribute/codereviews.md b/contribute/codereviews.md index 87ab392f1c..949cb11300 100644 --- a/contribute/codereviews.md +++ b/contribute/codereviews.md @@ -5,31 +5,23 @@ title: Code Review Contributions ## Code Review Contributions In addition to [bug fixing](./guide.html), you can help us review -[waiting pull requests](#pull_requests_awaiting_comment). This is also a good (and recommended) way to get to know the feel of -the bug-fixing and submissions process before jumping in (lurk for a while, -reading pull requests from others and maybe commenting on them). +[waiting pull requests](#pull_requests_awaiting_comment). +This is also a good (and recommended) way to get to know the feel of +the bug-fixing and submissions process before jumping in with your +own pull requests. -### Etiquette - -[Code of Conduct Reminder](http://docs.scala-lang.org/conduct.html) - -There are many coding approaches and styles. Asserting that yours is the only correct one is not likely to lead to a smooth interaction with others. Code review is where programmers (often volunteers) surrender up their efforts for public scrutiny. - -Code reviewing is a great way to both learn and mentor, and *all* comments made during pull request reviews should bear those two aims in mind. - -Assuming the pull request has been made following the guidelines laid out in the rest of the contributor documentation (e.g. for Scala bug fixes, the PR is against an open issue, and has adhered to the guidelines for code changes and submitting the PR), then the comments for the pull request are *not* the correct place to discuss on whether this PR is even needed or other broad, negative assertions. - -The comments are for looking for potential problems in the code, suggesting improvements, looking for items that might have been missed by the submitter and so on. If you feel it necessary to discuss whether the issue should even be addressed, that should be carried out ([in a professional manner](http://docs.scala-lang.org/conduct.html)) on the comments for that Issue rather than the PR. General discussions should likewise be directed to forums like [scala-debate](https://groups.google.com/d/forum/scala-debate), [scala-user](https://groups.google.com/d/forum/scala-user), [scala-language](https://groups.google.com/d/forum/scala-language) or [scala-internals](https://groups.google.com/d/forum/scala-internals). - -Conversely if you are receiving a review, consider that the advice is being given to make you, and Scala, better rather than as a negative critique. Assume the best, rather than the worst. ### Review Guidelines +[Code of Conduct Reminder](http://docs.scala-lang.org/conduct.html) + * Keep comments on-topic, concise and precise. * Attach comments to particular lines or regions they pertain to whenever possible. * Short code examples are often more descriptive than prose. -* If (and only if) you have thoroughly reviewed the PR and thought through all angles, and you want to accept it, LGTM (Looks Good To Me) is the preferred acceptance response. If there are already LGTMs on the PR, consider whether you are adding anything or just being "me too". -* Above all, remember that the people you are reviewing might be reviewing your PRs one day too :-). +* If you have thoroughly reviewed the PR and thought through all angles, LGTM (Looks Good To Me) is the preferred acceptance response. +* Additional reviews should try to offer additional insights: "I also thought about it from this angle and it still looks good.." +* Above all, remember that the people you are reviewing might be reviewing your PRs one day too. +* If you are receiving the review, consider that the advice is being given to make you, and Scala, better rather than as a negative critique. Assume the best, rather than the worst. ## Pull Requests Awaiting Comment @@ -57,4 +49,4 @@ Conversely if you are receiving a review, consider that the advice is being give
-Also note that the [Tools contributions](./tools.html) page has more projects that will generate pull requests. \ No newline at end of file +Also note that the [Tools contributions](./tools.html) page has more projects that will generate pull requests. From 3c9d4cd4b8587642f5d0b59f7a4ae7100d799904 Mon Sep 17 00:00:00 2001 From: Fabien Salvi Date: Tue, 14 Apr 2015 11:43:49 +0200 Subject: [PATCH 0076/3075] Add scala-fame data --- .../_posts/2015-03-01-scala-fame-2015-02.md | 70 ++++++++++++++ .../_posts/2015-04-01-scala-fame-2015-03.md | 91 +++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 contribute/scala-fame-data/_posts/2015-03-01-scala-fame-2015-02.md create mode 100644 contribute/scala-fame-data/_posts/2015-04-01-scala-fame-2015-03.md diff --git a/contribute/scala-fame-data/_posts/2015-03-01-scala-fame-2015-02.md b/contribute/scala-fame-data/_posts/2015-03-01-scala-fame-2015-02.md new file mode 100644 index 0000000000..3fe846623b --- /dev/null +++ b/contribute/scala-fame-data/_posts/2015-03-01-scala-fame-2015-02.md @@ -0,0 +1,70 @@ +--- +layout: famearchive +title: Contributors of February 2015 +fame-year: 2015 +fame-month: 2 +fame-month-str: February +fame-categories: + - category: Typesafe + authors: + - username: adriaanm + gravatar: https://avatars3.githubusercontent.com/u/91083?v=3&s=60 + commits: 15 + linesAdded: 1199 + linesDeleted: 588 + rank: 1 + newContributor: false + - username: retronym + gravatar: https://avatars1.githubusercontent.com/u/65551?v=3&s=60 + commits: 13 + linesAdded: 557 + linesDeleted: 64 + rank: 2 + newContributor: false + - category: EPFL + authors: + - username: lrytz + gravatar: https://avatars2.githubusercontent.com/u/119636?v=3&s=60 + commits: 10 + linesAdded: 1629 + linesDeleted: 276 + rank: 1 + newContributor: false + - username: xeno-by + gravatar: https://avatars0.githubusercontent.com/u/609152?v=3&s=60 + commits: 2 + linesAdded: 108 + linesDeleted: 15 + rank: 2 + newContributor: false + - username: axel22 + gravatar: https://avatars0.githubusercontent.com/u/151774?v=3&s=60 + commits: 1 + linesAdded: 61 + linesDeleted: 0 + rank: 3 + newContributor: false + - category: Community + authors: + - username: Ichoran + gravatar: https://avatars2.githubusercontent.com/u/2298644?v=3&s=60 + commits: 3 + linesAdded: 62 + linesDeleted: 25 + rank: 1 + newContributor: false + - username: som-snytt + gravatar: https://avatars3.githubusercontent.com/u/369425?v=3&s=60 + commits: 2 + linesAdded: 121 + linesDeleted: 30 + rank: 2 + newContributor: false + - username: milessabin + gravatar: https://avatars1.githubusercontent.com/u/131183?v=3&s=60 + commits: 1 + linesAdded: 123 + linesDeleted: 37 + rank: 3 + newContributor: false +--- diff --git a/contribute/scala-fame-data/_posts/2015-04-01-scala-fame-2015-03.md b/contribute/scala-fame-data/_posts/2015-04-01-scala-fame-2015-03.md new file mode 100644 index 0000000000..62e7ea2f58 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2015-04-01-scala-fame-2015-03.md @@ -0,0 +1,91 @@ +--- +layout: famearchive +title: Contributors of March 2015 +fame-year: 2015 +fame-month: 3 +fame-month-str: March +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://avatars1.githubusercontent.com/u/65551?v=3&s=60 + commits: 9 + linesAdded: 553 + linesDeleted: 27 + rank: 1 + newContributor: false + - username: adriaanm + gravatar: https://avatars3.githubusercontent.com/u/91083?v=3&s=60 + commits: 6 + linesAdded: 12 + linesDeleted: 72 + rank: 2 + newContributor: false + - category: EPFL + authors: + - username: lrytz + gravatar: https://avatars2.githubusercontent.com/u/119636?v=3&s=60 + commits: 18 + linesAdded: 2857 + linesDeleted: 916 + rank: 1 + newContributor: false + - username: xeno-by + gravatar: https://avatars0.githubusercontent.com/u/609152?v=3&s=60 + commits: 1 + linesAdded: 7 + linesDeleted: 5 + rank: 2 + newContributor: false + - category: Community + authors: + - username: gourlaysama + gravatar: https://avatars3.githubusercontent.com/u/733438?v=3&s=60 + commits: 4 + linesAdded: 132 + linesDeleted: 22 + rank: 1 + newContributor: false + - username: gbasler + gravatar: https://avatars0.githubusercontent.com/u/273035?v=3&s=60 + commits: 3 + linesAdded: 1986 + linesDeleted: 111 + rank: 2 + newContributor: false + - username: kzys + gravatar: https://avatars3.githubusercontent.com/u/19111?v=3&s=60 + commits: 2 + linesAdded: 37 + linesDeleted: 18 + rank: 3 + newContributor: false + - username: som-snytt + gravatar: https://avatars3.githubusercontent.com/u/369425?v=3&s=60 + commits: 2 + linesAdded: 91 + linesDeleted: 7 + rank: 3 + newContributor: false + - username: sschaef + gravatar: https://avatars3.githubusercontent.com/u/488530?v=3&s=60 + commits: 1 + linesAdded: 1 + linesDeleted: 1 + rank: 4 + newContributor: false + - username: khernyo + gravatar: https://avatars2.githubusercontent.com/u/447532?v=3&s=60 + commits: 1 + linesAdded: 27 + linesDeleted: 8 + rank: 4 + newContributor: false + - username: soc + gravatar: https://avatars1.githubusercontent.com/u/42493?v=3&s=60 + commits: 1 + linesAdded: 7 + linesDeleted: 7 + rank: 4 + newContributor: false +--- From 4bada26848285509763810ee5f2895123ced406c Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Mon, 20 Apr 2015 16:41:40 -0700 Subject: [PATCH 0077/3075] Fix transposition of github.scala.com. --- contribute/codereviews.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/codereviews.md b/contribute/codereviews.md index 949cb11300..8f86815eec 100644 --- a/contribute/codereviews.md +++ b/contribute/codereviews.md @@ -32,7 +32,7 @@ own pull requests.

Scala bug fixes and changes in the language, core libs and included tools.

-

scala/github.scala.com

+

scala/scala.github.com

Scala documentation site.

From 57b4392ae555e8d21edbd82e566813d30d38a6d2 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Mon, 13 Jul 2015 18:45:33 -0400 Subject: [PATCH 0078/3075] phase out old GitHub wiki pages https://github.com/scala/scala/wiki is going away --- contribute/hacker-guide.md | 2 +- contribute/scala-standard-library-api-documentation.md | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index ecdbd2fc27..3f84feee81 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -378,7 +378,7 @@ Let's go into each of these points in more detail. The [Git Basics](http://git-scm.com/book/en/Git-Basics) chapter in the Git online book covers most of the basic workflow during this stage. There are two things you should know here: -1. Commit messages are often the only way to understand the intentions of authors of code written a few years ago. Thus, writing a quality is of utmost importance. The more context you provide for the change you've introduced, the larger the chance that some future maintainer understand your intentions. Consult [the pull request policy](https://github.com/scala/scala/wiki/Pull-Request-Policy) for more information about the desired style of your commits. +1. Commit messages are often the only way to understand the intentions of authors of code written a few years ago. Thus, writing a quality is of utmost importance. The more context you provide for the change you've introduced, the larger the chance that some future maintainer understand your intentions. Consult [the pull request policies](https://github.com/scala/scala/blob/2.11.x/CONTRIBUTING.md) for more information about the desired style of your commits. 2. Keeping Scala's git history clean is also important. Therefore we won't accept pull requests for bug fixes that have more than one commit. For features, it is okay to have several commits, but all tests need to pass after every single commit. To clean up your commit structure, you want to [rewrite history](http://git-scm.com/book/en/Git-Branching-Rebasing) using `git rebase` so that your commits are against the latest revision of `master`. Once you are satisfied with your work, synced with `master` and cleaned up your commits you are ready to submit a patch to the central Scala repository. Before proceeding make sure you have pushed all of your local changes to your fork on GitHub. diff --git a/contribute/scala-standard-library-api-documentation.md b/contribute/scala-standard-library-api-documentation.md index 14eb55845c..bc57a163df 100644 --- a/contribute/scala-standard-library-api-documentation.md +++ b/contribute/scala-standard-library-api-documentation.md @@ -87,8 +87,7 @@ new API documentation to save time, effort, mistakes and repetition. and so on. * Prior to commit, be sure to read [A note about git commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) and the [Scala Project & Developer Guidelines](https://github.com/scala/scala/blob/2.11.x/CONTRIBUTING.md). -* Also read the Scala [Pull Request Policy](https://github.com/scala/scala/wiki/Pull-Request-Policy). - Some of this document will clearly not apply (like the sections on providing tests, + Some of this latter document will clearly not apply (like the sections on providing tests, however see below for some special requirements for documentation). Do still read the whole document though, and pay close attention to the title and commit message formats, noting *present tense*, *length limits* and that it must merge From 6a53d0605cb30cff874843aac7ce9a82855c783a Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Sat, 18 Jul 2015 14:03:43 -0400 Subject: [PATCH 0079/3075] hacker's guide: replace out-of-date reviewer list with link --- contribute/hacker-guide.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 3f84feee81..e8aa8f0db4 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -30,11 +30,9 @@ Typically bug fixes and new features start out as an idea or an experiment poste about things you want to implement. People proficient in certain areas of Scala usually monitor mailing lists, so you'll often get some help by simply posting a message. But the most efficient way to connect is to cc your message to one of the people responsible for maintaining the aspect of Scala which you wish to contribute to. -This is the list of language features/libraries along with their maintainer's full names and GitHub usernames: +A list of language features/libraries along with their maintainer's full names and GitHub usernames is [in the Scala repo README](https://github.com/scala/scala#get-in-touch). -{% include maintainers.html %} - -Since Martin is the person who submitted the string interpolation Scala Improvement Proposal and implemented this language feature for Scala 2.10.0, he might be interested in learning of new bugfixes to that feature. +In our running example, since Martin is the person who submitted the string interpolation Scala Improvement Proposal and implemented this language feature for Scala 2.10.0, he might be interested in learning of new bugfixes to that feature. As alluded to earlier, one must also choose an appropriate mailing list. Typically, one would use the scala-internals mailing list, as it is devoted to discussions about the core internal design and implementation of the Scala system. However, since this issue has been discussed previously on the scala-user mailing list, in this example, we post to the [the scala-user mailing list](http://groups.google.com/group/scala-user) about our issue. From 23f62743fffe21945f8c6cb454b2925b59fc960c Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Wed, 30 Sep 2015 13:18:35 +1000 Subject: [PATCH 0080/3075] SI-9495 Add note about configuring Ant for HTTP proxies --- contribute/hacker-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index e8aa8f0db4..3a01b6a676 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -99,7 +99,7 @@ If you are new to Git and branching, read the [Branching Chapter](http://git-scm The next step after cloning your fork is setting up your machine to build Scala. * It is recommended to use Java `1.6` (not `1.7` or `1.8`, because they might cause occasional glitches). -* The build tool is `ant`. +* The build tool is `ant`. If you are behind a HTTP proxy, include [`ANT_ARGS=-autoproxy`]( https://ant.apache.org/manual/proxy.html) in your environment. * The build runs the `pull-binary-libs.sh` script to download bootstrap libs. This requires `bash` and `curl`. * The majority of our team works on Linux and OS X, so these operating systems are guaranteed to work. * Windows is supported, but it might have issues. Please report to [the issue tracker](https://issues.scala-lang.org/) if you encounter any. From 4d8f053757a0feee1ac3d1b8e7bcb0f174b30203 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Wed, 30 Sep 2015 08:53:16 -0400 Subject: [PATCH 0081/3075] fix slightly malformed Markdown --- contribute/hacker-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 3a01b6a676..54e62c1a0e 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -99,7 +99,7 @@ If you are new to Git and branching, read the [Branching Chapter](http://git-scm The next step after cloning your fork is setting up your machine to build Scala. * It is recommended to use Java `1.6` (not `1.7` or `1.8`, because they might cause occasional glitches). -* The build tool is `ant`. If you are behind a HTTP proxy, include [`ANT_ARGS=-autoproxy`]( https://ant.apache.org/manual/proxy.html) in your environment. +* The build tool is `ant`. If you are behind a HTTP proxy, include [`ANT_ARGS=-autoproxy`](https://ant.apache.org/manual/proxy.html) in your environment. * The build runs the `pull-binary-libs.sh` script to download bootstrap libs. This requires `bash` and `curl`. * The majority of our team works on Linux and OS X, so these operating systems are guaranteed to work. * Windows is supported, but it might have issues. Please report to [the issue tracker](https://issues.scala-lang.org/) if you encounter any. From 50b14af581b26cce03f972a2d00a384d2f81ab08 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Tue, 6 Oct 2015 18:35:13 -0400 Subject: [PATCH 0082/3075] SI-9501 add prominent links to relevant docs in main Scala repo the text of the guide already links to the same documents at appropriate places in the narrative, but I also think it's worth having the same links right up front --- contribute/hacker-guide.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 54e62c1a0e..fb79d8166d 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -8,6 +8,8 @@ This guide is intended to help you get from an idea of fixing a bug or implement This guide covers the entire process, from the conception of your idea or bugfix to the point where it is merged into Scala. Throughout, we will use a running example of an idea or bugfix one might wish to contribute. +Other good starting points for first-time contributors include the [Scala README](https://github.com/scala/scala#get-in-touch) and [contributor's guidelines](https://github.com/scala/scala/blob/2.11.x/CONTRIBUTING.md). + ## The Running Example Let's say that you particularly enjoy the new string interpolation language feature introduced in Scala 2.10.0, and you use it quite heavily. From 0feb67ace760707b19b2c91a5f3afea1a9045ea7 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Fri, 6 Nov 2015 15:30:38 -0500 Subject: [PATCH 0083/3075] fix typo --- contribute/scala-fame.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/scala-fame.md b/contribute/scala-fame.md index 81bb76ee3a..f30784c13f 100644 --- a/contribute/scala-fame.md +++ b/contribute/scala-fame.md @@ -1,6 +1,6 @@ --- layout: page-full-width -title: Scala Contribuitor Hall of Fame +title: Scala Contributor Hall of Fame --- A big thank you to everyone who contributed to: From c80d07050db560e6aafadc659f9ca4d0b42ef3d2 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Fri, 6 Nov 2015 16:01:22 -0500 Subject: [PATCH 0084/3075] October 2015 hall of fame --- .../_posts/2015-11-01-scala-fame-2015-10.md | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 contribute/scala-fame-data/_posts/2015-11-01-scala-fame-2015-10.md diff --git a/contribute/scala-fame-data/_posts/2015-11-01-scala-fame-2015-10.md b/contribute/scala-fame-data/_posts/2015-11-01-scala-fame-2015-10.md new file mode 100644 index 0000000000..41698296db --- /dev/null +++ b/contribute/scala-fame-data/_posts/2015-11-01-scala-fame-2015-10.md @@ -0,0 +1,42 @@ +--- +layout: famearchive +title: Contributors of October 2015 +fame-year: 2015 +fame-month: 10 +fame-month-str: October +fame-categories: + - category: Typesafe + authors: + - username: SethTisue + gravatar: https://avatars.githubusercontent.com/u/161079?v=3 + commits: 9 + linesAdded: 80 + linesDeleted: 55 + rank: 1 + newContributor: false + - category: EPFL + authors: + - username: sjrd + gravatar: https://avatars.githubusercontent.com/u/535934?v=3 + commits: 1 + linesAdded: 1 + linesDeleted: 4 + rank: 1 + newContributor: false + - category: Community + authors: + - username: performantdata + gravatar: https://avatars.githubusercontent.com/u/6363453?v=3 + commits: 6 + linesAdded: 97 + linesDeleted: 50 + rank: 1 + newContributor: true + - username: janekdb + gravatar: https://avatars.githubusercontent.com/u/1123855?v=3 + commits: 1 + linesAdded: 86 + linesDeleted: 71 + rank: 2 + newContributor: false +--- From 761af814fe12baff772dcf47cb03c7943105d65d Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Fri, 6 Nov 2015 16:14:14 -0500 Subject: [PATCH 0085/3075] tweak Hall of Fame page * clarify what the stats show * link to the GitHub Pulse page, which is actually a lot better --- contribute/scala-fame.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/contribute/scala-fame.md b/contribute/scala-fame.md index f30784c13f..ffaf0980d7 100644 --- a/contribute/scala-fame.md +++ b/contribute/scala-fame.md @@ -3,10 +3,17 @@ layout: page-full-width title: Scala Contributor Hall of Fame --- -A big thank you to everyone who contributed to: +A big thank you to everyone who has contributed over the years to: - [the Scala library and compiler](https://github.com/scala/scala/contributors) - [the Scala documentation website](https://github.com/scala/scala.github.com/contributors) +What follows are the commit totals, to the 2.11.x branch of the scala/scala repo only, +for last month. (For a commit to be counted, it must have been both committed and merged +in the same month.) + +For more a detailed view of recent activity, see the repo's +[GitHub Pulse page](https://github.com/scala/scala/pulse/monthly). + {% for data in site.categories.scala-fame-data limit:1 %} {% assign famedata = data %} {% include render-scala-fame.html %} From 7a039ae25b191ce5733491062cf2f37d27192a9f Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Tue, 10 Nov 2015 15:16:42 -0500 Subject: [PATCH 0086/3075] tiny fix --- contribute/scala-fame.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/scala-fame.md b/contribute/scala-fame.md index ffaf0980d7..0352e6e7c7 100644 --- a/contribute/scala-fame.md +++ b/contribute/scala-fame.md @@ -11,7 +11,7 @@ What follows are the commit totals, to the 2.11.x branch of the scala/scala repo for last month. (For a commit to be counted, it must have been both committed and merged in the same month.) -For more a detailed view of recent activity, see the repo's +For a more detailed view of recent activity, see the repo's [GitHub Pulse page](https://github.com/scala/scala/pulse/monthly). {% for data in site.categories.scala-fame-data limit:1 %} From 749a690e43b43d9ff0aac267647eab842cd55045 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Fri, 4 Dec 2015 12:46:47 -0500 Subject: [PATCH 0087/3075] hall of fame: 2.12.x is default branch now --- contribute/scala-fame.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/scala-fame.md b/contribute/scala-fame.md index 0352e6e7c7..2be9e7d69d 100644 --- a/contribute/scala-fame.md +++ b/contribute/scala-fame.md @@ -7,7 +7,7 @@ A big thank you to everyone who has contributed over the years to: - [the Scala library and compiler](https://github.com/scala/scala/contributors) - [the Scala documentation website](https://github.com/scala/scala.github.com/contributors) -What follows are the commit totals, to the 2.11.x branch of the scala/scala repo only, +What follows are the commit totals, to the 2.12.x branch of the scala/scala repo only, for last month. (For a commit to be counted, it must have been both committed and merged in the same month.) From f0fb46ca9be30fc365b875d5ab2c9f171a55041b Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Fri, 4 Dec 2015 12:46:53 -0500 Subject: [PATCH 0088/3075] November 2015 contributors hall of fame --- .../_posts/2015-12-01-scala-fame-2015-11.md | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 contribute/scala-fame-data/_posts/2015-12-01-scala-fame-2015-11.md diff --git a/contribute/scala-fame-data/_posts/2015-12-01-scala-fame-2015-11.md b/contribute/scala-fame-data/_posts/2015-12-01-scala-fame-2015-11.md new file mode 100644 index 0000000000..8f9b7ff3b1 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2015-12-01-scala-fame-2015-11.md @@ -0,0 +1,63 @@ +--- +layout: famearchive +title: Contributors of November 2015 +fame-year: 2015 +fame-month: 11 +fame-month-str: November +fame-categories: + - category: Typesafe + authors: + - username: szeiger + gravatar: https://avatars.githubusercontent.com/u/54262?v=3 + commits: 5 + linesAdded: 427 + linesDeleted: 116 + rank: 1 + newContributor: false + - username: SethTisue + gravatar: https://avatars.githubusercontent.com/u/161079?v=3 + commits: 3 + linesAdded: 21 + linesDeleted: 21 + rank: 2 + newContributor: false + - username: retronym + gravatar: https://avatars.githubusercontent.com/u/65551?v=3 + commits: 3 + linesAdded: 44 + linesDeleted: 28 + rank: 2 + newContributor: false + - username: adriaanm + gravatar: https://avatars.githubusercontent.com/u/91083?v=3 + commits: 2 + linesAdded: 22 + linesDeleted: 25 + rank: 3 + newContributor: false + - username: lrytz + gravatar: https://avatars.githubusercontent.com/u/119636?v=3 + commits: 1 + linesAdded: 7 + linesDeleted: 18 + rank: 4 + newContributor: false + - category: EPFL + authors: + - category: Community + authors: + - username: janekdb + gravatar: https://avatars.githubusercontent.com/u/1123855?v=3 + commits: 6 + linesAdded: 76 + linesDeleted: 63 + rank: 1 + newContributor: false + - username: soc + gravatar: https://avatars.githubusercontent.com/u/42493?v=3 + commits: 2 + linesAdded: 14 + linesDeleted: 19 + rank: 2 + newContributor: false +--- From f928c829f2e0dad88a7f0cfaabfd2d4ce87d8da5 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Thu, 17 Dec 2015 15:35:33 -0500 Subject: [PATCH 0089/3075] fix bad Markdown our Markdown processor needs a blank line before the start of a bullet list --- contribute/scala-fame.md | 1 + 1 file changed, 1 insertion(+) diff --git a/contribute/scala-fame.md b/contribute/scala-fame.md index 2be9e7d69d..4b6591004a 100644 --- a/contribute/scala-fame.md +++ b/contribute/scala-fame.md @@ -4,6 +4,7 @@ title: Scala Contributor Hall of Fame --- A big thank you to everyone who has contributed over the years to: + - [the Scala library and compiler](https://github.com/scala/scala/contributors) - [the Scala documentation website](https://github.com/scala/scala.github.com/contributors) From 719edc3d277d67b41aef833f4edf568b47ae90d8 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Thu, 17 Dec 2015 18:43:23 -0500 Subject: [PATCH 0090/3075] add text about community libraries, Scala community build --- contribute/index.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/contribute/index.md b/contribute/index.md index fd94af5de2..c03405e489 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -101,3 +101,31 @@ various contributor activities: + +### Tools and Libraries + +The Scala ecosystem includes a great many diverse open-source projects +with their own maintainers and community of contributors. Helping out +one of these projects is another way to help Scala. Consider lending +on a hand on a project you're already using. Or, to find out about +other projects, see the +[Libraries and Tools section](../community/index.html#community-libraries-and-tools) +on our Community page. + +### Scala Community Build + +The Scala community build enables us to build and test a corpus of +Scala open source projects together, using Typesafe's +[dbuild](https://github.com/typesafehub/dbuild) tool +(which leverages [sbt](http://www.scala-sbt.org)). + +The main goal is to guard against regressions in new versions of Scala +(language, standard library, and modules). It's also a service to the +open source community, providing early notice of issues and +incompatibilities. + +If you're the maintainer -- or just an interested user! -- of an +open-source Scala library or tool, please visit the +[community build documentation](https://github.com/scala/community-builds/wiki) +for guidelines on what projects are suitable for the community build +and how projects can be added. From eeee725f7c666a969e823f128dd6893a34a3d0d8 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Thu, 17 Dec 2015 18:56:12 -0500 Subject: [PATCH 0091/3075] Code of Conduct page, relocated from docs site with updated links, and addition of link to site footer --- contribute/codereviews.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/codereviews.md b/contribute/codereviews.md index 8f86815eec..1b9a881b0c 100644 --- a/contribute/codereviews.md +++ b/contribute/codereviews.md @@ -13,7 +13,7 @@ own pull requests. ### Review Guidelines -[Code of Conduct Reminder](http://docs.scala-lang.org/conduct.html) +[Code of Conduct reminder](../conduct.html) * Keep comments on-topic, concise and precise. * Attach comments to particular lines or regions they pertain to whenever possible. From cc3d461d8fe51112d5d5b6b721f078025469a795 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Fri, 18 Dec 2015 07:48:57 -0500 Subject: [PATCH 0092/3075] tweak wording of community build section based on Heather's feedback --- contribute/index.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/contribute/index.md b/contribute/index.md index c03405e489..137838aba4 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -114,15 +114,14 @@ on our Community page. ### Scala Community Build -The Scala community build enables us to build and test a corpus of -Scala open source projects together, using Typesafe's -[dbuild](https://github.com/typesafehub/dbuild) tool -(which leverages [sbt](http://www.scala-sbt.org)). - -The main goal is to guard against regressions in new versions of Scala -(language, standard library, and modules). It's also a service to the -open source community, providing early notice of issues and -incompatibilities. +The Scala community build enables the Scala compiler team +to build and test a corpus of +Scala open source projects +against development versions of the Scala compiler and standard +library in order to discover regressions prior to releases. +The build uses Typesafe's +[dbuild](https://github.com/typesafehub/dbuild) tool, +which leverages [sbt](http://www.scala-sbt.org). If you're the maintainer -- or just an interested user! -- of an open-source Scala library or tool, please visit the From 856fc9cb2f903ad3353ed49e15d15e70de01e07f Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Mon, 4 Jan 2016 17:27:39 -0500 Subject: [PATCH 0093/3075] retire the Scala Contributor Hall of Fame https://api.github.com/repos/scala/scala/stats/contributors wasn't giving us good information to base this on, because it only gives you the top 100 contributors by number of all-time commits so e.g. Felix Mulder's great Scaladoc contribution for December wasn't even showing up in the data, since it was just one commit. one of the main purposes of this page was supposed to be recognizing new contributors, but the 100-contributor limit prevents that. the result was embarrassingly empty pages (which we usually forgot to even update anyway) if people are interested in all-time stats, they can visit https://github.com/scala/scala/graphs/contributors , and if people want to see recent activity, they can visit https://github.com/scala/scala/pulse --- contribute/guide.md | 2 +- .../_posts/2013-02-01-scala-fame-2013-01.md | 175 ---------------- .../_posts/2013-03-01-scala-fame-2013-02.md | 189 ------------------ .../_posts/2013-04-01-scala-fame-2013-03.md | 147 -------------- .../_posts/2013-05-01-scala-fame-2013-04.md | 126 ------------ .../_posts/2013-06-01-scala-fame-2013-05.md | 105 ---------- .../_posts/2013-07-01-scala-fame-2013-06.md | 126 ------------ .../_posts/2013-08-01-scala-fame-2013-07.md | 119 ----------- .../_posts/2013-09-01-scala-fame-2013-08.md | 98 --------- .../_posts/2013-10-01-scala-fame-2013-09.md | 105 ---------- .../_posts/2013-11-01-scala-fame-2013-10.md | 105 ---------- .../_posts/2013-12-01-scala-fame-2013-11.md | 126 ------------ .../_posts/2014-01-01-scala-fame-2013-12.md | 147 -------------- .../_posts/2014-02-01-scala-fame-2014-01.md | 147 -------------- .../_posts/2014-03-01-scala-fame-2014-02.md | 133 ------------ .../_posts/2014-04-01-scala-fame-2014-03.md | 112 ----------- .../_posts/2014-05-01-scala-fame-2014-04.md | 91 --------- .../_posts/2014-06-01-scala-fame-2014-05.md | 112 ----------- .../_posts/2014-07-01-scala-fame-2014-06.md | 98 --------- .../_posts/2014-08-01-scala-fame-2014-07.md | 98 --------- .../_posts/2014-09-01-scala-fame-2014-08.md | 70 ------- .../_posts/2014-10-01-scala-fame-2014-09.md | 84 -------- .../_posts/2014-11-01-scala-fame-2014-10.md | 63 ------ .../_posts/2014-12-01-scala-fame-2014-11.md | 112 ----------- .../_posts/2015-01-01-scala-fame-2014-12.md | 70 ------- .../_posts/2015-02-01-scala-fame-2015-01.md | 56 ------ .../_posts/2015-03-01-scala-fame-2015-02.md | 70 ------- .../_posts/2015-04-01-scala-fame-2015-03.md | 91 --------- .../_posts/2015-11-01-scala-fame-2015-10.md | 42 ---- .../_posts/2015-12-01-scala-fame-2015-11.md | 63 ------ contribute/scala-fame.md | 21 -- 31 files changed, 1 insertion(+), 3102 deletions(-) delete mode 100644 contribute/scala-fame-data/_posts/2013-02-01-scala-fame-2013-01.md delete mode 100644 contribute/scala-fame-data/_posts/2013-03-01-scala-fame-2013-02.md delete mode 100644 contribute/scala-fame-data/_posts/2013-04-01-scala-fame-2013-03.md delete mode 100644 contribute/scala-fame-data/_posts/2013-05-01-scala-fame-2013-04.md delete mode 100644 contribute/scala-fame-data/_posts/2013-06-01-scala-fame-2013-05.md delete mode 100644 contribute/scala-fame-data/_posts/2013-07-01-scala-fame-2013-06.md delete mode 100644 contribute/scala-fame-data/_posts/2013-08-01-scala-fame-2013-07.md delete mode 100644 contribute/scala-fame-data/_posts/2013-09-01-scala-fame-2013-08.md delete mode 100644 contribute/scala-fame-data/_posts/2013-10-01-scala-fame-2013-09.md delete mode 100644 contribute/scala-fame-data/_posts/2013-11-01-scala-fame-2013-10.md delete mode 100644 contribute/scala-fame-data/_posts/2013-12-01-scala-fame-2013-11.md delete mode 100644 contribute/scala-fame-data/_posts/2014-01-01-scala-fame-2013-12.md delete mode 100644 contribute/scala-fame-data/_posts/2014-02-01-scala-fame-2014-01.md delete mode 100644 contribute/scala-fame-data/_posts/2014-03-01-scala-fame-2014-02.md delete mode 100644 contribute/scala-fame-data/_posts/2014-04-01-scala-fame-2014-03.md delete mode 100644 contribute/scala-fame-data/_posts/2014-05-01-scala-fame-2014-04.md delete mode 100644 contribute/scala-fame-data/_posts/2014-06-01-scala-fame-2014-05.md delete mode 100644 contribute/scala-fame-data/_posts/2014-07-01-scala-fame-2014-06.md delete mode 100644 contribute/scala-fame-data/_posts/2014-08-01-scala-fame-2014-07.md delete mode 100644 contribute/scala-fame-data/_posts/2014-09-01-scala-fame-2014-08.md delete mode 100644 contribute/scala-fame-data/_posts/2014-10-01-scala-fame-2014-09.md delete mode 100644 contribute/scala-fame-data/_posts/2014-11-01-scala-fame-2014-10.md delete mode 100644 contribute/scala-fame-data/_posts/2014-12-01-scala-fame-2014-11.md delete mode 100644 contribute/scala-fame-data/_posts/2015-01-01-scala-fame-2014-12.md delete mode 100644 contribute/scala-fame-data/_posts/2015-02-01-scala-fame-2015-01.md delete mode 100644 contribute/scala-fame-data/_posts/2015-03-01-scala-fame-2015-02.md delete mode 100644 contribute/scala-fame-data/_posts/2015-04-01-scala-fame-2015-03.md delete mode 100644 contribute/scala-fame-data/_posts/2015-11-01-scala-fame-2015-10.md delete mode 100644 contribute/scala-fame-data/_posts/2015-12-01-scala-fame-2015-11.md delete mode 100644 contribute/scala-fame.md diff --git a/contribute/guide.md b/contribute/guide.md index 04fe50ae5b..148ceb7570 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -35,7 +35,7 @@ Just to name a few common reasons: * contributing a patch is the best way to make sure your desired changes will be available in the next Scala version * Scala is written in Scala, so going through the source code and patching it will improve your Scala-fu -* last but not least, you will make it into the [Scala Contributor Hall of Fame](scala-fame.html). +* last but not least, it only takes a few accepted commits to make it into the [Scala Contributor Hall of Fame](https://github.com/scala/scala/contributors). The main Scala project consists of the standard Scala library, the Scala reflection and macros library, the Scala compiler and the Scaladoc tool. This means there's plenty to choose from when deciding what to work on. diff --git a/contribute/scala-fame-data/_posts/2013-02-01-scala-fame-2013-01.md b/contribute/scala-fame-data/_posts/2013-02-01-scala-fame-2013-01.md deleted file mode 100644 index 68e990a7b7..0000000000 --- a/contribute/scala-fame-data/_posts/2013-02-01-scala-fame-2013-01.md +++ /dev/null @@ -1,175 +0,0 @@ ---- -layout: famearchive -title: Contributors of January 2013 -fame-year: 2013 -fame-month: 1 -fame-month-str: January -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 - commits: 67 - linesAdded: 7112 - linesDeleted: 3063 - rank: 1 - newContributor: false - - username: paulp - gravatar: https://avatars2.githubusercontent.com/u/9135?v=2&s=60 - commits: 37 - linesAdded: 1812 - linesDeleted: 1158 - rank: 2 - newContributor: false - - username: adriaanm - gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 - commits: 22 - linesAdded: 1397 - linesDeleted: 561 - rank: 3 - newContributor: false - - username: JamesIry - gravatar: https://avatars0.githubusercontent.com/u/478012?v=2&s=60 - commits: 20 - linesAdded: 1156 - linesDeleted: 208 - rank: 4 - newContributor: false - - username: gkossakowski - gravatar: https://avatars0.githubusercontent.com/u/4217?v=2&s=60 - commits: 5 - linesAdded: 422 - linesDeleted: 9 - rank: 5 - newContributor: false - - username: viktorklang - gravatar: https://avatars0.githubusercontent.com/u/10871?v=2&s=60 - commits: 2 - linesAdded: 187 - linesDeleted: 12 - rank: 6 - newContributor: false - - username: phaller - gravatar: https://avatars0.githubusercontent.com/u/289943?v=2&s=60 - commits: 2 - linesAdded: 21 - linesDeleted: 42 - rank: 6 - newContributor: false - - username: dragos - gravatar: https://avatars2.githubusercontent.com/u/133742?v=2&s=60 - commits: 1 - linesAdded: 6 - linesDeleted: 26 - rank: 7 - newContributor: false - - category: EPFL - authors: - - username: xeno-by - gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 - commits: 28 - linesAdded: 8416 - linesDeleted: 2758 - rank: 1 - newContributor: false - - username: lrytz - gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 - commits: 8 - linesAdded: 1189 - linesDeleted: 418 - rank: 2 - newContributor: false - - username: heathermiller - gravatar: https://avatars0.githubusercontent.com/u/687163?v=2&s=60 - commits: 2 - linesAdded: 100 - linesDeleted: 15 - rank: 3 - newContributor: false - - username: namin - gravatar: https://avatars2.githubusercontent.com/u/6441?v=2&s=60 - commits: 1 - linesAdded: 23 - linesDeleted: 4 - rank: 4 - newContributor: false - - username: vjovanov - gravatar: https://avatars3.githubusercontent.com/u/352820?v=2&s=60 - commits: 1 - linesAdded: 38 - linesDeleted: 2 - rank: 4 - newContributor: false - - category: Community - authors: - - username: soc - gravatar: https://avatars0.githubusercontent.com/u/42493?v=2&s=60 - commits: 13 - linesAdded: 886 - linesDeleted: 3152 - rank: 1 - newContributor: false - - username: kzys - gravatar: https://avatars2.githubusercontent.com/u/19111?v=2&s=60 - commits: 7 - linesAdded: 79 - linesDeleted: 40 - rank: 2 - newContributor: false - - username: danielhopkins - gravatar: https://avatars3.githubusercontent.com/u/91909?v=2&s=60 - commits: 2 - linesAdded: 146 - linesDeleted: 146 - rank: 3 - newContributor: true - - username: ViniciusMiana - gravatar: https://avatars1.githubusercontent.com/u/2053546?v=2&s=60 - commits: 2 - linesAdded: 47 - linesDeleted: 8 - rank: 3 - newContributor: false - - username: Blaisorblade - gravatar: https://avatars2.githubusercontent.com/u/289960?v=2&s=60 - commits: 2 - linesAdded: 53 - linesDeleted: 6 - rank: 3 - newContributor: false - - username: som-snytt - gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 - commits: 2 - linesAdded: 236 - linesDeleted: 183 - rank: 3 - newContributor: false - - username: eed3si9n - gravatar: https://avatars1.githubusercontent.com/u/184683?v=2&s=60 - commits: 1 - linesAdded: 35 - linesDeleted: 2 - rank: 4 - newContributor: false - - username: mt2309 - gravatar: https://avatars2.githubusercontent.com/u/816245?v=2&s=60 - commits: 1 - linesAdded: 24 - linesDeleted: 0 - rank: 4 - newContributor: false - - username: puffnfresh - gravatar: https://avatars1.githubusercontent.com/u/37715?v=2&s=60 - commits: 1 - linesAdded: 39 - linesDeleted: 3 - rank: 4 - newContributor: false - - username: khernyo - gravatar: https://avatars3.githubusercontent.com/u/447532?v=2&s=60 - commits: 1 - linesAdded: 2 - linesDeleted: 3 - rank: 4 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2013-03-01-scala-fame-2013-02.md b/contribute/scala-fame-data/_posts/2013-03-01-scala-fame-2013-02.md deleted file mode 100644 index 376563abce..0000000000 --- a/contribute/scala-fame-data/_posts/2013-03-01-scala-fame-2013-02.md +++ /dev/null @@ -1,189 +0,0 @@ ---- -layout: famearchive -title: Contributors of February 2013 -fame-year: 2013 -fame-month: 2 -fame-month-str: February -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://secure.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 38 - linesAdded: 2578 - linesDeleted: 2114 - rank: 1 - newContributor: false - - username: adriaanm - gravatar: https://secure.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 31 - linesAdded: 7110 - linesDeleted: 9889 - rank: 2 - newContributor: false - - username: JamesIry - gravatar: https://secure.gravatar.com/avatar/72b1a6b08fd8bb3068bd281974461c3e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 23 - linesAdded: 1673 - linesDeleted: 740 - rank: 3 - newContributor: false - - username: paulp - gravatar: https://secure.gravatar.com/avatar/c25d674f69bb9c155f265a7482712be4?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 10 - linesAdded: 1466 - linesDeleted: 1097 - rank: 4 - newContributor: false - - username: viktorklang - gravatar: https://secure.gravatar.com/avatar/4f674b2e79f1663864ff78e07ce4c8a8?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 3 - linesAdded: 84 - linesDeleted: 53 - rank: 5 - newContributor: false - - username: gkossakowski - gravatar: https://secure.gravatar.com/avatar/e608c8cb27858cc5aaf7d0c1e57958d7?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 2 - linesAdded: 4 - linesDeleted: 1 - rank: 6 - newContributor: false - - username: huitseeker - gravatar: https://secure.gravatar.com/avatar/dc11aab8ab70b10a828b5ee4735183e8?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 26 - linesDeleted: 0 - rank: 7 - newContributor: false - - username: rkuhn - gravatar: https://secure.gravatar.com/avatar/262b1ab25e66b1e15a48fa3f68703aad?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 3 - linesDeleted: 2 - rank: 7 - newContributor: false - - category: EPFL - authors: - - username: xeno-by - gravatar: https://secure.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 36 - linesAdded: 3379 - linesDeleted: 1635 - rank: 1 - newContributor: false - - username: lrytz - gravatar: https://secure.gravatar.com/avatar/d807dd5133a6fc14c821178e53c34091?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 3 - linesAdded: 213 - linesDeleted: 31 - rank: 2 - newContributor: false - - username: heathermiller - gravatar: https://secure.gravatar.com/avatar/54d0b6494927c0040b96ed327202e8dc?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 2 - linesAdded: 2 - linesDeleted: 1333 - rank: 3 - newContributor: false - - username: VladUreche - gravatar: https://secure.gravatar.com/avatar/5658ed1cea041577df360fd663c570fa?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 2 - linesAdded: 86 - linesDeleted: 32 - rank: 3 - newContributor: false - - username: hubertp - gravatar: https://secure.gravatar.com/avatar/e0dec64f93778e5c689c3873078a406f?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 2 - linesAdded: 297 - linesDeleted: 100 - rank: 3 - newContributor: false - - username: axel22 - gravatar: https://secure.gravatar.com/avatar/e9bdb4fada7e635fffb5e6f26e70cd1d?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 9 - linesDeleted: 106 - rank: 4 - newContributor: false - - category: Community - authors: - - username: vigdorchik - gravatar: https://secure.gravatar.com/avatar/d497b1b875b7f68414daff74485b8501?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 4 - linesAdded: 471 - linesDeleted: 410 - rank: 1 - newContributor: false - - username: vy - gravatar: https://secure.gravatar.com/avatar/bb8d759cf4230bcaa238fac0018af80c?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 2 - linesAdded: 21 - linesDeleted: 21 - rank: 2 - newContributor: true - - username: u-abramchuk - gravatar: https://secure.gravatar.com/avatar/c70eb13a60582914b51966fdc1a18536?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 2 - linesAdded: 47 - linesDeleted: 13 - rank: 2 - newContributor: true - - username: jozic - gravatar: https://secure.gravatar.com/avatar/41fbba6d48e543a7dfa8c231b2d0286d?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 8 - linesDeleted: 8 - rank: 3 - newContributor: true - - username: rnix - gravatar: https://secure.gravatar.com/avatar/0dcbf348a28f2295164c53a40d48a958?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 1 - linesDeleted: 1 - rank: 3 - newContributor: true - - username: mergeconflict - gravatar: https://secure.gravatar.com/avatar/9a58682929b182af7b01f0180e072fcd?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 22 - linesDeleted: 15 - rank: 3 - newContributor: false - - username: mt2309 - gravatar: https://secure.gravatar.com/avatar/f70e1d36b9c1b9290d31e810fa1502f3?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 3 - linesDeleted: 0 - rank: 3 - newContributor: false - - username: ViniciusMiana - gravatar: https://secure.gravatar.com/avatar/e05e828a92458c4075b498c7d2957ddd?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 16 - linesDeleted: 0 - rank: 3 - newContributor: false - - username: Blaisorblade - gravatar: https://secure.gravatar.com/avatar/a3a676c96a88feb813010e67af012ca0?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 0 - linesDeleted: 3 - rank: 3 - newContributor: false - - username: khernyo - gravatar: https://secure.gravatar.com/avatar/0e0d750a49edb4b16e8ec83816ea356e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 25 - linesDeleted: 1 - rank: 3 - newContributor: false - - username: som-snytt - gravatar: https://secure.gravatar.com/avatar/ec5b08d0fe94845ba49fd4a263c7d99d?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 1 - linesDeleted: 1 - rank: 3 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2013-04-01-scala-fame-2013-03.md b/contribute/scala-fame-data/_posts/2013-04-01-scala-fame-2013-03.md deleted file mode 100644 index 0feb88618a..0000000000 --- a/contribute/scala-fame-data/_posts/2013-04-01-scala-fame-2013-03.md +++ /dev/null @@ -1,147 +0,0 @@ ---- -layout: famearchive -title: Contributors of March 2013 -fame-year: 2013 -fame-month: 3 -fame-month-str: March -fame-categories: - - category: Typesafe - authors: - - username: paulp - gravatar: https://secure.gravatar.com/avatar/c25d674f69bb9c155f265a7482712be4?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 51 - linesAdded: 38101 - linesDeleted: 37753 - rank: 1 - newContributor: false - - username: retronym - gravatar: https://secure.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 46 - linesAdded: 4908 - linesDeleted: 3092 - rank: 2 - newContributor: false - - username: adriaanm - gravatar: https://secure.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 27 - linesAdded: 2675 - linesDeleted: 5043 - rank: 3 - newContributor: false - - username: JamesIry - gravatar: https://secure.gravatar.com/avatar/72b1a6b08fd8bb3068bd281974461c3e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 7 - linesAdded: 1218 - linesDeleted: 171 - rank: 4 - newContributor: false - - username: dragos - gravatar: https://secure.gravatar.com/avatar/fbd384e9626d28d1648f023a5e22672f?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 169 - linesDeleted: 2 - rank: 5 - newContributor: false - - category: EPFL - authors: - - username: xeno-by - gravatar: https://secure.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 11 - linesAdded: 295 - linesDeleted: 129 - rank: 1 - newContributor: false - - username: magarciaEPFL - gravatar: https://secure.gravatar.com/avatar/94ff1d59d6e0a3a4ab10c80ab12bfeed?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 6 - linesAdded: 89 - linesDeleted: 44 - rank: 2 - newContributor: false - - category: Community - authors: - - username: vigdorchik - gravatar: https://secure.gravatar.com/avatar/d497b1b875b7f68414daff74485b8501?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 9 - linesAdded: 714 - linesDeleted: 619 - rank: 1 - newContributor: false - - username: som-snytt - gravatar: https://secure.gravatar.com/avatar/ec5b08d0fe94845ba49fd4a263c7d99d?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 7 - linesAdded: 2103 - linesDeleted: 2068 - rank: 2 - newContributor: false - - username: soc - gravatar: https://secure.gravatar.com/avatar/6e4171314f4704b1e82aa4e5d9067e92?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 6 - linesAdded: 166 - linesDeleted: 96 - rank: 3 - newContributor: false - - username: kzys - gravatar: https://secure.gravatar.com/avatar/7828b45f8396aa361d85cead01fd99ca?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 5 - linesAdded: 129 - linesDeleted: 41 - rank: 4 - newContributor: false - - username: Blaisorblade - gravatar: https://secure.gravatar.com/avatar/a3a676c96a88feb813010e67af012ca0?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 3 - linesAdded: 72 - linesDeleted: 20 - rank: 5 - newContributor: false - - username: starblood - gravatar: https://secure.gravatar.com/avatar/bd3514b960213c6a7ff5fd3186675429?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 1 - linesDeleted: 1 - rank: 6 - newContributor: true - - username: srinivasreddy - gravatar: https://secure.gravatar.com/avatar/1f542afb3240b82fdf08632bf6cd5384?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 1 - linesDeleted: 1 - rank: 6 - newContributor: true - - username: mesagie - gravatar: https://secure.gravatar.com/avatar/6e7dc465ed74b5250147168a0178d91c?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 4 - linesDeleted: 5 - rank: 6 - newContributor: true - - username: mergeconflict - gravatar: https://secure.gravatar.com/avatar/9a58682929b182af7b01f0180e072fcd?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 22 - linesDeleted: 15 - rank: 6 - newContributor: false - - username: sschaef - gravatar: https://secure.gravatar.com/avatar/dd80aab570fdb5f37e62de5422f44ed4?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 13 - linesDeleted: 0 - rank: 6 - newContributor: false - - username: ihji - gravatar: https://secure.gravatar.com/avatar/866a258f0c9fa9529aa47ebd96fe599c?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 33 - linesDeleted: 6 - rank: 6 - newContributor: false - - username: chuvoks - gravatar: https://secure.gravatar.com/avatar/415869059046602f37803890bd992fc0?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 45 - linesDeleted: 24 - rank: 6 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2013-05-01-scala-fame-2013-04.md b/contribute/scala-fame-data/_posts/2013-05-01-scala-fame-2013-04.md deleted file mode 100644 index e2cd419e9b..0000000000 --- a/contribute/scala-fame-data/_posts/2013-05-01-scala-fame-2013-04.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -layout: famearchive -title: Contributors of April 2013 -fame-year: 2013 -fame-month: 4 -fame-month-str: April -fame-categories: - - category: Typesafe - authors: - - username: paulp - gravatar: https://secure.gravatar.com/avatar/c25d674f69bb9c155f265a7482712be4?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 38 - linesAdded: 3745 - linesDeleted: 2973 - rank: 1 - newContributor: false - - username: retronym - gravatar: https://secure.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 37 - linesAdded: 1309 - linesDeleted: 777 - rank: 2 - newContributor: false - - username: huitseeker - gravatar: https://secure.gravatar.com/avatar/dc11aab8ab70b10a828b5ee4735183e8?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 3 - linesAdded: 16 - linesDeleted: 24 - rank: 3 - newContributor: false - - username: adriaanm - gravatar: https://secure.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 2 - linesAdded: 35 - linesDeleted: 82 - rank: 4 - newContributor: false - - category: EPFL - authors: - - username: magarciaEPFL - gravatar: https://secure.gravatar.com/avatar/94ff1d59d6e0a3a4ab10c80ab12bfeed?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 11 - linesAdded: 238 - linesDeleted: 204 - rank: 1 - newContributor: false - - username: xeno-by - gravatar: https://secure.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 4 - linesAdded: 208 - linesDeleted: 121 - rank: 2 - newContributor: false - - username: namin - gravatar: https://secure.gravatar.com/avatar/f2adf4eb83e1221b519d23bf0bdc98d2?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 6 - linesDeleted: 11 - rank: 3 - newContributor: false - - username: heathermiller - gravatar: https://secure.gravatar.com/avatar/54d0b6494927c0040b96ed327202e8dc?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 1 - linesDeleted: 1 - rank: 3 - newContributor: false - - username: hubertp - gravatar: https://secure.gravatar.com/avatar/e0dec64f93778e5c689c3873078a406f?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 54 - linesDeleted: 46 - rank: 3 - newContributor: false - - category: Community - authors: - - username: som-snytt - gravatar: https://secure.gravatar.com/avatar/ec5b08d0fe94845ba49fd4a263c7d99d?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 16 - linesAdded: 2561 - linesDeleted: 1150 - rank: 1 - newContributor: false - - username: vigdorchik - gravatar: https://secure.gravatar.com/avatar/d497b1b875b7f68414daff74485b8501?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 9 - linesAdded: 235 - linesDeleted: 321 - rank: 2 - newContributor: false - - username: soc - gravatar: https://secure.gravatar.com/avatar/6e4171314f4704b1e82aa4e5d9067e92?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 4 - linesAdded: 38 - linesDeleted: 26 - rank: 3 - newContributor: false - - username: ihji - gravatar: https://secure.gravatar.com/avatar/866a258f0c9fa9529aa47ebd96fe599c?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 2 - linesAdded: 13 - linesDeleted: 2 - rank: 4 - newContributor: false - - username: bjornregnell - gravatar: https://secure.gravatar.com/avatar/b1d20c98b0eeb72829523144b9174ca2?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 3 - linesDeleted: 2 - rank: 5 - newContributor: true - - username: aldenml - gravatar: https://secure.gravatar.com/avatar/bbf061bd484515c156f662a65820c226?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 4 - linesDeleted: 4 - rank: 5 - newContributor: true - - username: eed3si9n - gravatar: https://secure.gravatar.com/avatar/8f41595db400be30176f6f04630c2842?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 304 - linesDeleted: 6 - rank: 5 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2013-06-01-scala-fame-2013-05.md b/contribute/scala-fame-data/_posts/2013-06-01-scala-fame-2013-05.md deleted file mode 100644 index 2829d6a4aa..0000000000 --- a/contribute/scala-fame-data/_posts/2013-06-01-scala-fame-2013-05.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -layout: famearchive -title: Contributors of May 2013 -fame-year: 2013 -fame-month: 5 -fame-month-str: May -fame-categories: - - category: Typesafe - authors: - - username: paulp - gravatar: https://secure.gravatar.com/avatar/c25d674f69bb9c155f265a7482712be4?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 54 - linesAdded: 3465 - linesDeleted: 2035 - rank: 1 - newContributor: false - - username: retronym - gravatar: https://secure.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 13 - linesAdded: 525 - linesDeleted: 66 - rank: 2 - newContributor: false - - username: adriaanm - gravatar: https://secure.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 5 - linesAdded: 245 - linesDeleted: 81 - rank: 3 - newContributor: false - - username: viktorklang - gravatar: https://secure.gravatar.com/avatar/4f674b2e79f1663864ff78e07ce4c8a8?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 2 - linesAdded: 51 - linesDeleted: 32 - rank: 4 - newContributor: false - - username: phaller - gravatar: https://secure.gravatar.com/avatar/3b84657fdb075382e3781310ca8a9a70?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 1965 - linesDeleted: 1086 - rank: 5 - newContributor: false - - category: EPFL - authors: - - username: xeno-by - gravatar: https://secure.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 19 - linesAdded: 742 - linesDeleted: 468 - rank: 1 - newContributor: false - - username: magarciaEPFL - gravatar: https://secure.gravatar.com/avatar/94ff1d59d6e0a3a4ab10c80ab12bfeed?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 11 - linesAdded: 1214 - linesDeleted: 1069 - rank: 2 - newContributor: false - - username: heathermiller - gravatar: https://secure.gravatar.com/avatar/54d0b6494927c0040b96ed327202e8dc?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 10 - linesDeleted: 7 - rank: 3 - newContributor: false - - category: Community - authors: - - username: soc - gravatar: https://secure.gravatar.com/avatar/6e4171314f4704b1e82aa4e5d9067e92?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 12 - linesAdded: 254 - linesDeleted: 1135 - rank: 1 - newContributor: false - - username: som-snytt - gravatar: https://secure.gravatar.com/avatar/ec5b08d0fe94845ba49fd4a263c7d99d?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 6 - linesAdded: 454 - linesDeleted: 403 - rank: 2 - newContributor: false - - username: vigdorchik - gravatar: https://secure.gravatar.com/avatar/d497b1b875b7f68414daff74485b8501?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 2 - linesAdded: 42 - linesDeleted: 32 - rank: 3 - newContributor: false - - username: dcsobral - gravatar: https://secure.gravatar.com/avatar/6d43da5df0e52fc31c55e6a227bb23f4?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 6 - linesDeleted: 2 - rank: 4 - newContributor: false - - username: kzys - gravatar: https://secure.gravatar.com/avatar/7828b45f8396aa361d85cead01fd99ca?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 25 - linesDeleted: 9 - rank: 4 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2013-07-01-scala-fame-2013-06.md b/contribute/scala-fame-data/_posts/2013-07-01-scala-fame-2013-06.md deleted file mode 100644 index e2fa22bf84..0000000000 --- a/contribute/scala-fame-data/_posts/2013-07-01-scala-fame-2013-06.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -layout: famearchive -title: Contributors of June 2013 -fame-year: 2013 -fame-month: 6 -fame-month-str: June -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://secure.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 18 - linesAdded: 3583 - linesDeleted: 60 - rank: 1 - newContributor: false - - username: adriaanm - gravatar: https://secure.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 13 - linesAdded: 12207 - linesDeleted: 11500 - rank: 2 - newContributor: false - - username: paulp - gravatar: https://secure.gravatar.com/avatar/c25d674f69bb9c155f265a7482712be4?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 6 - linesAdded: 264 - linesDeleted: 1625 - rank: 3 - newContributor: false - - username: gkossakowski - gravatar: https://secure.gravatar.com/avatar/e608c8cb27858cc5aaf7d0c1e57958d7?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 3 - linesAdded: 296 - linesDeleted: 176 - rank: 4 - newContributor: false - - username: viktorklang - gravatar: https://secure.gravatar.com/avatar/4f674b2e79f1663864ff78e07ce4c8a8?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 2 - linesAdded: 197 - linesDeleted: 546 - rank: 5 - newContributor: false - - username: huitseeker - gravatar: https://secure.gravatar.com/avatar/dc11aab8ab70b10a828b5ee4735183e8?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 32 - linesDeleted: 1 - rank: 6 - newContributor: false - - category: EPFL - authors: - - username: magarciaEPFL - gravatar: https://secure.gravatar.com/avatar/94ff1d59d6e0a3a4ab10c80ab12bfeed?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 5 - linesAdded: 29 - linesDeleted: 27 - rank: 1 - newContributor: false - - username: VladUreche - gravatar: https://secure.gravatar.com/avatar/5658ed1cea041577df360fd663c570fa?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 4 - linesAdded: 383 - linesDeleted: 68 - rank: 2 - newContributor: false - - username: xeno-by - gravatar: https://secure.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 2 - linesAdded: 57 - linesDeleted: 15 - rank: 3 - newContributor: false - - category: Community - authors: - - username: soc - gravatar: https://secure.gravatar.com/avatar/6e4171314f4704b1e82aa4e5d9067e92?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 12 - linesAdded: 1071 - linesDeleted: 1200 - rank: 1 - newContributor: false - - username: som-snytt - gravatar: https://secure.gravatar.com/avatar/ec5b08d0fe94845ba49fd4a263c7d99d?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 5 - linesAdded: 273 - linesDeleted: 44 - rank: 2 - newContributor: false - - username: lexspoon - gravatar: https://secure.gravatar.com/avatar/d00741a2082647573efc2c15022ad15c?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 5 - linesAdded: 90 - linesDeleted: 29 - rank: 2 - newContributor: false - - username: jedesah - gravatar: https://secure.gravatar.com/avatar/188a972e1c0a6d678a59bd6bce46da9a?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 3 - linesAdded: 23 - linesDeleted: 2 - rank: 3 - newContributor: false - - username: yllan - gravatar: https://secure.gravatar.com/avatar/ad23f5809b32c9dade553f80d6d7b2b9?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 2 - linesAdded: 124 - linesDeleted: 4 - rank: 4 - newContributor: true - - username: jannic - gravatar: https://secure.gravatar.com/avatar/c85c7cbcc9d464e178ba751449f893c7?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 9 - linesDeleted: 0 - rank: 5 - newContributor: false - - username: xuwei-k - gravatar: https://secure.gravatar.com/avatar/18d8b1bf73827b2a15e2bd3e75b4b34a?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 2 - linesDeleted: 2 - rank: 5 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2013-08-01-scala-fame-2013-07.md b/contribute/scala-fame-data/_posts/2013-08-01-scala-fame-2013-07.md deleted file mode 100644 index b6670c42ce..0000000000 --- a/contribute/scala-fame-data/_posts/2013-08-01-scala-fame-2013-07.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -layout: famearchive -title: Contributors of July 2013 -fame-year: 2013 -fame-month: 7 -fame-month-str: July -fame-categories: - - category: Typesafe - authors: - - username: gkossakowski - gravatar: https://0.gravatar.com/avatar/e608c8cb27858cc5aaf7d0c1e57958d7?d=https%3A%2F%2Fidenticons.github.com%2F8196e8d0f9ee7dfdfc7e11dbbfa30d77.png&s=60 - commits: 11 - linesAdded: 522 - linesDeleted: 311 - rank: 1 - newContributor: false - - username: adriaanm - gravatar: https://0.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?d=https%3A%2F%2Fidenticons.github.com%2Ff0d91e20ef53ace520f6ccbf8402319f.png&s=60 - commits: 9 - linesAdded: 1068 - linesDeleted: 11436 - rank: 2 - newContributor: false - - username: retronym - gravatar: https://0.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?d=https%3A%2F%2Fidenticons.github.com%2F75e4dffe50001cf8b96d3beecbe181be.png&s=60 - commits: 8 - linesAdded: 416 - linesDeleted: 134 - rank: 3 - newContributor: false - - username: paulp - gravatar: https://identicons.github.com/bf65417dcecc7f2b0006e1f5793b7143.png - commits: 2 - linesAdded: 46 - linesDeleted: 27 - rank: 4 - newContributor: false - - category: EPFL - authors: - - username: magarciaEPFL - gravatar: https://2.gravatar.com/avatar/94ff1d59d6e0a3a4ab10c80ab12bfeed?d=https%3A%2F%2Fidenticons.github.com%2F8b7440eff98d923640c99b5535429144.png&s=60 - commits: 12 - linesAdded: 1208 - linesDeleted: 1069 - rank: 1 - newContributor: false - - username: xeno-by - gravatar: https://2.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?d=https%3A%2F%2Fidenticons.github.com%2F6a5b1b05e953818962474e94b67d1cc2.png&s=60 - commits: 8 - linesAdded: 321 - linesDeleted: 95 - rank: 2 - newContributor: false - - username: VladUreche - gravatar: https://2.gravatar.com/avatar/5658ed1cea041577df360fd663c570fa?d=https%3A%2F%2Fidenticons.github.com%2Fa1ef2fed16f85a1af890467a80c30226.png&s=60 - commits: 2 - linesAdded: 104 - linesDeleted: 2 - rank: 3 - newContributor: false - - username: cvogt - gravatar: https://1.gravatar.com/avatar/669fb4eab529fba02f390051ddf3c8d3?d=https%3A%2F%2Fidenticons.github.com%2F78d9e7d7c73ac19ca8da9805762e5bb0.png&s=60 - commits: 1 - linesAdded: 19 - linesDeleted: 0 - rank: 4 - newContributor: false - - category: Community - authors: - - username: soc - gravatar: https://0.gravatar.com/avatar/6e4171314f4704b1e82aa4e5d9067e92?d=https%3A%2F%2Fidenticons.github.com%2F29f7ac3adbe1d3500c9404388aedcbfd.png&s=60 - commits: 19 - linesAdded: 2818 - linesDeleted: 4377 - rank: 1 - newContributor: false - - username: som-snytt - gravatar: https://2.gravatar.com/avatar/ec5b08d0fe94845ba49fd4a263c7d99d?d=https%3A%2F%2Fidenticons.github.com%2Fd292a902ebb73981efd65c9ef416046b.png&s=60 - commits: 16 - linesAdded: 1049 - linesDeleted: 553 - rank: 2 - newContributor: false - - username: densh - gravatar: https://0.gravatar.com/avatar/5ed274e115ec061d062d9c32a539cdc9?d=https%3A%2F%2Fidenticons.github.com%2Fcd3e73ab183ea35424f0bf59101a74e4.png&s=60 - commits: 9 - linesAdded: 2632 - linesDeleted: 178 - rank: 3 - newContributor: false - - username: folone - gravatar: https://2.gravatar.com/avatar/50e7e3f60b3507383d2b327857b66a62?d=https%3A%2F%2Fidenticons.github.com%2F6c2bcbccd23191b40f4932e2b8450681.png&s=60 - commits: 3 - linesAdded: 106 - linesDeleted: 261 - rank: 4 - newContributor: false - - username: xuwei-k - gravatar: https://2.gravatar.com/avatar/18d8b1bf73827b2a15e2bd3e75b4b34a?d=https%3A%2F%2Fidenticons.github.com%2Fdab0069935d770e6285411ed1f4398b9.png&s=60 - commits: 3 - linesAdded: 5 - linesDeleted: 5 - rank: 4 - newContributor: false - - username: gourlaysama - gravatar: https://2.gravatar.com/avatar/8acf3c87222f89b18786c8db60eb365d?d=https%3A%2F%2Fidenticons.github.com%2F76004d7b1fac3a2b262caa5e6bdf15c9.png&s=60 - commits: 2 - linesAdded: 67 - linesDeleted: 3 - rank: 5 - newContributor: false - - username: ScrapCodes - gravatar: https://0.gravatar.com/avatar/e9813bbbab2caa993bf7e2b2d60de894?d=https%3A%2F%2Fidenticons.github.com%2F38c660c74f82a216b75167debab770ed.png&s=60 - commits: 1 - linesAdded: 1 - linesDeleted: 1 - rank: 6 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2013-09-01-scala-fame-2013-08.md b/contribute/scala-fame-data/_posts/2013-09-01-scala-fame-2013-08.md deleted file mode 100644 index c876e815d1..0000000000 --- a/contribute/scala-fame-data/_posts/2013-09-01-scala-fame-2013-08.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -layout: famearchive -title: Contributors of August 2013 -fame-year: 2013 -fame-month: 8 -fame-month-str: August -fame-categories: - - category: Typesafe - authors: - - username: paulp - gravatar: https://identicons.github.com/bf65417dcecc7f2b0006e1f5793b7143.png - commits: 50 - linesAdded: 3703 - linesDeleted: 2269 - rank: 1 - newContributor: false - - username: retronym - gravatar: https://0.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?d=https%3A%2F%2Fidenticons.github.com%2F75e4dffe50001cf8b96d3beecbe181be.png&s=60 - commits: 30 - linesAdded: 990 - linesDeleted: 167 - rank: 2 - newContributor: false - - username: adriaanm - gravatar: https://0.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?d=https%3A%2F%2Fidenticons.github.com%2Ff0d91e20ef53ace520f6ccbf8402319f.png&s=60 - commits: 6 - linesAdded: 224 - linesDeleted: 11001 - rank: 3 - newContributor: false - - username: huitseeker - gravatar: https://0.gravatar.com/avatar/dc11aab8ab70b10a828b5ee4735183e8?d=https%3A%2F%2Fidenticons.github.com%2F0777acff7c9ab34562699e4e1d05affb.png&s=60 - commits: 2 - linesAdded: 6 - linesDeleted: 6 - rank: 4 - newContributor: false - - category: EPFL - authors: - - username: xeno-by - gravatar: https://2.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?d=https%3A%2F%2Fidenticons.github.com%2F6a5b1b05e953818962474e94b67d1cc2.png&s=60 - commits: 9 - linesAdded: 579 - linesDeleted: 419 - rank: 1 - newContributor: false - - username: magarciaEPFL - gravatar: https://2.gravatar.com/avatar/94ff1d59d6e0a3a4ab10c80ab12bfeed?d=https%3A%2F%2Fidenticons.github.com%2F8b7440eff98d923640c99b5535429144.png&s=60 - commits: 4 - linesAdded: 319 - linesDeleted: 105 - rank: 2 - newContributor: false - - category: Community - authors: - - username: densh - gravatar: https://0.gravatar.com/avatar/5ed274e115ec061d062d9c32a539cdc9?d=https%3A%2F%2Fidenticons.github.com%2Fcd3e73ab183ea35424f0bf59101a74e4.png&s=60 - commits: 19 - linesAdded: 687 - linesDeleted: 322 - rank: 1 - newContributor: false - - username: som-snytt - gravatar: https://2.gravatar.com/avatar/ec5b08d0fe94845ba49fd4a263c7d99d?d=https%3A%2F%2Fidenticons.github.com%2Fd292a902ebb73981efd65c9ef416046b.png&s=60 - commits: 12 - linesAdded: 455 - linesDeleted: 91 - rank: 2 - newContributor: false - - username: soc - gravatar: https://0.gravatar.com/avatar/6e4171314f4704b1e82aa4e5d9067e92?d=https%3A%2F%2Fidenticons.github.com%2F29f7ac3adbe1d3500c9404388aedcbfd.png&s=60 - commits: 4 - linesAdded: 64 - linesDeleted: 27 - rank: 3 - newContributor: false - - username: gourlaysama - gravatar: https://2.gravatar.com/avatar/8acf3c87222f89b18786c8db60eb365d?d=https%3A%2F%2Fidenticons.github.com%2F76004d7b1fac3a2b262caa5e6bdf15c9.png&s=60 - commits: 2 - linesAdded: 50 - linesDeleted: 9 - rank: 4 - newContributor: false - - username: ScrapCodes - gravatar: https://0.gravatar.com/avatar/e9813bbbab2caa993bf7e2b2d60de894?d=https%3A%2F%2Fidenticons.github.com%2F38c660c74f82a216b75167debab770ed.png&s=60 - commits: 1 - linesAdded: 3 - linesDeleted: 0 - rank: 5 - newContributor: false - - username: folone - gravatar: https://2.gravatar.com/avatar/50e7e3f60b3507383d2b327857b66a62?d=https%3A%2F%2Fidenticons.github.com%2F6c2bcbccd23191b40f4932e2b8450681.png&s=60 - commits: 1 - linesAdded: 55 - linesDeleted: 7 - rank: 5 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2013-10-01-scala-fame-2013-09.md b/contribute/scala-fame-data/_posts/2013-10-01-scala-fame-2013-09.md deleted file mode 100644 index 23fa456fc0..0000000000 --- a/contribute/scala-fame-data/_posts/2013-10-01-scala-fame-2013-09.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -layout: famearchive -title: Contributors of September 2013 -fame-year: 2013 -fame-month: 9 -fame-month-str: September -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://2.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?d=https%3A%2F%2Fidenticons.github.com%2F75e4dffe50001cf8b96d3beecbe181be.png&s=60 - commits: 42 - linesAdded: 1459 - linesDeleted: 476 - rank: 1 - newContributor: false - - username: paulp - gravatar: https://identicons.github.com/bf65417dcecc7f2b0006e1f5793b7143.png - commits: 25 - linesAdded: 6603 - linesDeleted: 7419 - rank: 2 - newContributor: false - - username: huitseeker - gravatar: https://1.gravatar.com/avatar/dc11aab8ab70b10a828b5ee4735183e8?d=https%3A%2F%2Fidenticons.github.com%2F0777acff7c9ab34562699e4e1d05affb.png&s=60 - commits: 7 - linesAdded: 520 - linesDeleted: 536 - rank: 3 - newContributor: false - - username: gkossakowski - gravatar: https://0.gravatar.com/avatar/e608c8cb27858cc5aaf7d0c1e57958d7?d=https%3A%2F%2Fidenticons.github.com%2F8196e8d0f9ee7dfdfc7e11dbbfa30d77.png&s=60 - commits: 2 - linesAdded: 1443 - linesDeleted: 44 - rank: 4 - newContributor: false - - username: dragos - gravatar: https://2.gravatar.com/avatar/fbd384e9626d28d1648f023a5e22672f?d=https%3A%2F%2Fidenticons.github.com%2F6b660454242c937e501b88fd136132f8.png&s=60 - commits: 2 - linesAdded: 95 - linesDeleted: 13 - rank: 4 - newContributor: false - - username: jsuereth - gravatar: https://1.gravatar.com/avatar/5ed293320c06809a24812f56861201ad?d=https%3A%2F%2Fidenticons.github.com%2F11a5b5ef81cff76a0a1f3d042f635df3.png&s=60 - commits: 1 - linesAdded: 18 - linesDeleted: 37 - rank: 5 - newContributor: false - - username: adriaanm - gravatar: https://0.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?d=https%3A%2F%2Fidenticons.github.com%2Ff0d91e20ef53ace520f6ccbf8402319f.png&s=60 - commits: 1 - linesAdded: 5 - linesDeleted: 5 - rank: 5 - newContributor: false - - category: EPFL - authors: - - username: xeno-by - gravatar: https://1.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?d=https%3A%2F%2Fidenticons.github.com%2F6a5b1b05e953818962474e94b67d1cc2.png&s=60 - commits: 5 - linesAdded: 434 - linesDeleted: 153 - rank: 1 - newContributor: false - - username: sjrd - gravatar: https://1.gravatar.com/avatar/bc554c7355c8476dd63375b314b1bd97?d=https%3A%2F%2Fidenticons.github.com%2F7f7549008d59643d2ce9846ce0364947.png&s=60 - commits: 4 - linesAdded: 30 - linesDeleted: 9 - rank: 2 - newContributor: true - - category: Community - authors: - - username: densh - gravatar: https://1.gravatar.com/avatar/5ed274e115ec061d062d9c32a539cdc9?d=https%3A%2F%2Fidenticons.github.com%2Fcd3e73ab183ea35424f0bf59101a74e4.png&s=60 - commits: 20 - linesAdded: 1415 - linesDeleted: 594 - rank: 1 - newContributor: false - - username: som-snytt - gravatar: https://1.gravatar.com/avatar/ec5b08d0fe94845ba49fd4a263c7d99d?d=https%3A%2F%2Fidenticons.github.com%2Fd292a902ebb73981efd65c9ef416046b.png&s=60 - commits: 11 - linesAdded: 367 - linesDeleted: 106 - rank: 2 - newContributor: false - - username: Ichoran - gravatar: https://0.gravatar.com/avatar/3698349ad0b898d398a6573f4d1f867a?d=https%3A%2F%2Fidenticons.github.com%2Ffc12483537f3df99d480423de674e099.png&s=60 - commits: 3 - linesAdded: 75 - linesDeleted: 27 - rank: 3 - newContributor: true - - username: sschaef - gravatar: https://0.gravatar.com/avatar/dd80aab570fdb5f37e62de5422f44ed4?d=https%3A%2F%2Fidenticons.github.com%2Fb5a662bc30d97b377338f5dfb2b4cc66.png&s=60 - commits: 3 - linesAdded: 84 - linesDeleted: 139 - rank: 3 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2013-11-01-scala-fame-2013-10.md b/contribute/scala-fame-data/_posts/2013-11-01-scala-fame-2013-10.md deleted file mode 100644 index 557955d60c..0000000000 --- a/contribute/scala-fame-data/_posts/2013-11-01-scala-fame-2013-10.md +++ /dev/null @@ -1,105 +0,0 @@ ---- -layout: famearchive -title: Contributors of October 2013 -fame-year: 2013 -fame-month: 10 -fame-month-str: October -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 - commits: 52 - linesAdded: 1917 - linesDeleted: 1778 - rank: 1 - newContributor: false - - username: adriaanm - gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 - commits: 18 - linesAdded: 1648 - linesDeleted: 1591 - rank: 2 - newContributor: false - - username: paulp - gravatar: https://avatars2.githubusercontent.com/u/9135?v=2&s=60 - commits: 9 - linesAdded: 871 - linesDeleted: 1346 - rank: 3 - newContributor: false - - username: huitseeker - gravatar: https://avatars2.githubusercontent.com/u/4142?v=2&s=60 - commits: 1 - linesAdded: 3 - linesDeleted: 0 - rank: 4 - newContributor: false - - category: EPFL - authors: - - username: xeno-by - gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 - commits: 9 - linesAdded: 398 - linesDeleted: 2260 - rank: 1 - newContributor: false - - username: axel22 - gravatar: https://avatars1.githubusercontent.com/u/151774?v=2&s=60 - commits: 1 - linesAdded: 201 - linesDeleted: 74 - rank: 2 - newContributor: false - - category: Community - authors: - - username: densh - gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 - commits: 18 - linesAdded: 766 - linesDeleted: 422 - rank: 1 - newContributor: false - - username: som-snytt - gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 - commits: 4 - linesAdded: 114 - linesDeleted: 58 - rank: 2 - newContributor: false - - username: etaty - gravatar: https://avatars3.githubusercontent.com/u/461170?v=2&s=60 - commits: 2 - linesAdded: 2 - linesDeleted: 2 - rank: 3 - newContributor: false - - username: dotta - gravatar: https://avatars2.githubusercontent.com/u/703748?v=2&s=60 - commits: 2 - linesAdded: 68 - linesDeleted: 6 - rank: 3 - newContributor: false - - username: qerub - gravatar: https://avatars2.githubusercontent.com/u/636?v=2&s=60 - commits: 1 - linesAdded: 8 - linesDeleted: 0 - rank: 4 - newContributor: false - - username: gourlaysama - gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 - commits: 1 - linesAdded: 31 - linesDeleted: 1 - rank: 4 - newContributor: false - - username: Ichoran - gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 - commits: 1 - linesAdded: 215 - linesDeleted: 25 - rank: 4 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2013-12-01-scala-fame-2013-11.md b/contribute/scala-fame-data/_posts/2013-12-01-scala-fame-2013-11.md deleted file mode 100644 index 7fba955998..0000000000 --- a/contribute/scala-fame-data/_posts/2013-12-01-scala-fame-2013-11.md +++ /dev/null @@ -1,126 +0,0 @@ ---- -layout: famearchive -title: Contributors of November 2013 -fame-year: 2013 -fame-month: 11 -fame-month-str: November -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 - commits: 44 - linesAdded: 1814 - linesDeleted: 1372 - rank: 1 - newContributor: false - - username: adriaanm - gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 - commits: 20 - linesAdded: 1945 - linesDeleted: 1463 - rank: 2 - newContributor: false - - username: paulp - gravatar: https://avatars2.githubusercontent.com/u/9135?v=2&s=60 - commits: 4 - linesAdded: 62 - linesDeleted: 659 - rank: 3 - newContributor: false - - username: huitseeker - gravatar: https://avatars2.githubusercontent.com/u/4142?v=2&s=60 - commits: 2 - linesAdded: 137 - linesDeleted: 87 - rank: 4 - newContributor: false - - username: phaller - gravatar: https://avatars0.githubusercontent.com/u/289943?v=2&s=60 - commits: 1 - linesAdded: 105 - linesDeleted: 101 - rank: 5 - newContributor: false - - category: EPFL - authors: - - username: xeno-by - gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 - commits: 5 - linesAdded: 82 - linesDeleted: 12 - rank: 1 - newContributor: false - - username: heathermiller - gravatar: https://avatars0.githubusercontent.com/u/687163?v=2&s=60 - commits: 1 - linesAdded: 8 - linesDeleted: 5 - rank: 2 - newContributor: false - - category: Community - authors: - - username: densh - gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 - commits: 10 - linesAdded: 1089 - linesDeleted: 884 - rank: 1 - newContributor: false - - username: skyluc - gravatar: https://avatars3.githubusercontent.com/u/1098830?v=2&s=60 - commits: 6 - linesAdded: 1911 - linesDeleted: 53 - rank: 2 - newContributor: false - - username: dotta - gravatar: https://avatars2.githubusercontent.com/u/703748?v=2&s=60 - commits: 6 - linesAdded: 64 - linesDeleted: 47 - rank: 2 - newContributor: false - - username: som-snytt - gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 - commits: 6 - linesAdded: 499 - linesDeleted: 197 - rank: 2 - newContributor: false - - username: soc - gravatar: https://avatars0.githubusercontent.com/u/42493?v=2&s=60 - commits: 5 - linesAdded: 280 - linesDeleted: 97 - rank: 3 - newContributor: false - - username: sschaef - gravatar: https://avatars2.githubusercontent.com/u/488530?v=2&s=60 - commits: 4 - linesAdded: 182 - linesDeleted: 12 - rank: 4 - newContributor: false - - username: xuwei-k - gravatar: https://avatars3.githubusercontent.com/u/389787?v=2&s=60 - commits: 2 - linesAdded: 3 - linesDeleted: 3 - rank: 5 - newContributor: false - - username: Ichoran - gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 - commits: 2 - linesAdded: 1179 - linesDeleted: 0 - rank: 5 - newContributor: false - - username: Blaisorblade - gravatar: https://avatars2.githubusercontent.com/u/289960?v=2&s=60 - commits: 1 - linesAdded: 3 - linesDeleted: 3 - rank: 6 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2014-01-01-scala-fame-2013-12.md b/contribute/scala-fame-data/_posts/2014-01-01-scala-fame-2013-12.md deleted file mode 100644 index 80c4139b10..0000000000 --- a/contribute/scala-fame-data/_posts/2014-01-01-scala-fame-2013-12.md +++ /dev/null @@ -1,147 +0,0 @@ ---- -layout: famearchive -title: Contributors of December 2013 -fame-year: 2013 -fame-month: 12 -fame-month-str: December -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 - commits: 28 - linesAdded: 901 - linesDeleted: 215 - rank: 1 - newContributor: false - - username: adriaanm - gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 - commits: 21 - linesAdded: 1386 - linesDeleted: 16746 - rank: 2 - newContributor: false - - username: paulp - gravatar: https://avatars2.githubusercontent.com/u/9135?v=2&s=60 - commits: 9 - linesAdded: 899 - linesDeleted: 409 - rank: 3 - newContributor: false - - username: huitseeker - gravatar: https://avatars2.githubusercontent.com/u/4142?v=2&s=60 - commits: 3 - linesAdded: 45 - linesDeleted: 38 - rank: 4 - newContributor: false - - category: EPFL - authors: - - username: xeno-by - gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 - commits: 30 - linesAdded: 2170 - linesDeleted: 984 - rank: 1 - newContributor: false - - username: magarciaEPFL - gravatar: https://avatars2.githubusercontent.com/u/1249748?v=2&s=60 - commits: 5 - linesAdded: 47 - linesDeleted: 17 - rank: 2 - newContributor: false - - category: Community - authors: - - username: densh - gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 - commits: 20 - linesAdded: 1604 - linesDeleted: 703 - rank: 1 - newContributor: false - - username: soc - gravatar: https://avatars0.githubusercontent.com/u/42493?v=2&s=60 - commits: 11 - linesAdded: 728 - linesDeleted: 606 - rank: 2 - newContributor: false - - username: Ichoran - gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 - commits: 8 - linesAdded: 1490 - linesDeleted: 286 - rank: 3 - newContributor: false - - username: som-snytt - gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 - commits: 6 - linesAdded: 382 - linesDeleted: 224 - rank: 4 - newContributor: false - - username: dotta - gravatar: https://avatars2.githubusercontent.com/u/703748?v=2&s=60 - commits: 5 - linesAdded: 265 - linesDeleted: 13 - rank: 5 - newContributor: false - - username: VladimirNik - gravatar: https://avatars2.githubusercontent.com/u/2835001?v=2&s=60 - commits: 2 - linesAdded: 7 - linesDeleted: 8 - rank: 6 - newContributor: false - - username: rklaehn - gravatar: https://avatars0.githubusercontent.com/u/248257?v=2&s=60 - commits: 2 - linesAdded: 2 - linesDeleted: 83 - rank: 6 - newContributor: false - - username: qerub - gravatar: https://avatars2.githubusercontent.com/u/636?v=2&s=60 - commits: 1 - linesAdded: 10 - linesDeleted: 11 - rank: 7 - newContributor: false - - username: jrudolph - gravatar: https://avatars1.githubusercontent.com/u/9868?v=2&s=60 - commits: 1 - linesAdded: 4 - linesDeleted: 4 - rank: 7 - newContributor: false - - username: skyluc - gravatar: https://avatars3.githubusercontent.com/u/1098830?v=2&s=60 - commits: 1 - linesAdded: 112 - linesDeleted: 54 - rank: 7 - newContributor: false - - username: non - gravatar: https://avatars3.githubusercontent.com/u/218045?v=2&s=60 - commits: 1 - linesAdded: 19 - linesDeleted: 8 - rank: 7 - newContributor: false - - username: xuwei-k - gravatar: https://avatars3.githubusercontent.com/u/389787?v=2&s=60 - commits: 1 - linesAdded: 1 - linesDeleted: 1 - rank: 7 - newContributor: false - - username: gourlaysama - gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 - commits: 1 - linesAdded: 136 - linesDeleted: 55 - rank: 7 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2014-02-01-scala-fame-2014-01.md b/contribute/scala-fame-data/_posts/2014-02-01-scala-fame-2014-01.md deleted file mode 100644 index ab8e808036..0000000000 --- a/contribute/scala-fame-data/_posts/2014-02-01-scala-fame-2014-01.md +++ /dev/null @@ -1,147 +0,0 @@ ---- -layout: famearchive -title: Contributors of January 2014 -fame-year: 2014 -fame-month: 1 -fame-month-str: January -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 - commits: 37 - linesAdded: 2000 - linesDeleted: 2487 - rank: 1 - newContributor: false - - username: adriaanm - gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 - commits: 8 - linesAdded: 311 - linesDeleted: 175 - rank: 2 - newContributor: false - - username: gkossakowski - gravatar: https://avatars0.githubusercontent.com/u/4217?v=2&s=60 - commits: 3 - linesAdded: 15 - linesDeleted: 5 - rank: 3 - newContributor: false - - username: huitseeker - gravatar: https://avatars2.githubusercontent.com/u/4142?v=2&s=60 - commits: 2 - linesAdded: 81 - linesDeleted: 79 - rank: 4 - newContributor: false - - username: paulp - gravatar: https://avatars2.githubusercontent.com/u/9135?v=2&s=60 - commits: 2 - linesAdded: 7 - linesDeleted: 5 - rank: 4 - newContributor: false - - category: EPFL - authors: - - username: xeno-by - gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 - commits: 75 - linesAdded: 8908 - linesDeleted: 6023 - rank: 1 - newContributor: false - - category: Community - authors: - - username: densh - gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 - commits: 16 - linesAdded: 722 - linesDeleted: 295 - rank: 1 - newContributor: false - - username: Ichoran - gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 - commits: 10 - linesAdded: 315 - linesDeleted: 103 - rank: 2 - newContributor: false - - username: som-snytt - gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 - commits: 9 - linesAdded: 646 - linesDeleted: 201 - rank: 3 - newContributor: false - - username: VladimirNik - gravatar: https://avatars2.githubusercontent.com/u/2835001?v=2&s=60 - commits: 7 - linesAdded: 1729 - linesDeleted: 350 - rank: 4 - newContributor: false - - username: rklaehn - gravatar: https://avatars0.githubusercontent.com/u/248257?v=2&s=60 - commits: 6 - linesAdded: 1288 - linesDeleted: 39 - rank: 5 - newContributor: false - - username: gourlaysama - gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 - commits: 3 - linesAdded: 37 - linesDeleted: 7 - rank: 6 - newContributor: false - - username: cunei - gravatar: https://avatars2.githubusercontent.com/u/686260?v=2&s=60 - commits: 2 - linesAdded: 42 - linesDeleted: 12 - rank: 7 - newContributor: false - - username: Blaisorblade - gravatar: https://avatars2.githubusercontent.com/u/289960?v=2&s=60 - commits: 2 - linesAdded: 51 - linesDeleted: 33 - rank: 7 - newContributor: false - - username: havocp - gravatar: https://avatars2.githubusercontent.com/u/218689?v=2&s=60 - commits: 1 - linesAdded: 38 - linesDeleted: 2 - rank: 8 - newContributor: false - - username: clhodapp - gravatar: https://avatars0.githubusercontent.com/u/108633?v=2&s=60 - commits: 1 - linesAdded: 22 - linesDeleted: 0 - rank: 8 - newContributor: false - - username: rjolly - gravatar: https://avatars3.githubusercontent.com/u/128610?v=2&s=60 - commits: 1 - linesAdded: 45 - linesDeleted: 38 - rank: 8 - newContributor: false - - username: xuwei-k - gravatar: https://avatars3.githubusercontent.com/u/389787?v=2&s=60 - commits: 1 - linesAdded: 1 - linesDeleted: 1 - rank: 8 - newContributor: false - - username: dotta - gravatar: https://avatars2.githubusercontent.com/u/703748?v=2&s=60 - commits: 1 - linesAdded: 67 - linesDeleted: 67 - rank: 8 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2014-03-01-scala-fame-2014-02.md b/contribute/scala-fame-data/_posts/2014-03-01-scala-fame-2014-02.md deleted file mode 100644 index 065ab45d13..0000000000 --- a/contribute/scala-fame-data/_posts/2014-03-01-scala-fame-2014-02.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -layout: famearchive -title: Contributors of February 2014 -fame-year: 2014 -fame-month: 2 -fame-month-str: February -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 - commits: 47 - linesAdded: 1533 - linesDeleted: 1032 - rank: 1 - newContributor: false - - username: adriaanm - gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 - commits: 25 - linesAdded: 1043 - linesDeleted: 491 - rank: 2 - newContributor: false - - username: gkossakowski - gravatar: https://avatars0.githubusercontent.com/u/4217?v=2&s=60 - commits: 4 - linesAdded: 1867 - linesDeleted: 1747 - rank: 3 - newContributor: false - - username: paulp - gravatar: https://avatars2.githubusercontent.com/u/9135?v=2&s=60 - commits: 3 - linesAdded: 427 - linesDeleted: 15 - rank: 4 - newContributor: false - - username: dragos - gravatar: https://avatars2.githubusercontent.com/u/133742?v=2&s=60 - commits: 1 - linesAdded: 12 - linesDeleted: 3 - rank: 5 - newContributor: false - - category: EPFL - authors: - - username: xeno-by - gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 - commits: 47 - linesAdded: 3989 - linesDeleted: 1545 - rank: 1 - newContributor: false - - username: lrytz - gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 - commits: 1 - linesAdded: 18 - linesDeleted: 13 - rank: 2 - newContributor: false - - category: Community - authors: - - username: densh - gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 - commits: 23 - linesAdded: 1166 - linesDeleted: 515 - rank: 1 - newContributor: false - - username: VladimirNik - gravatar: https://avatars2.githubusercontent.com/u/2835001?v=2&s=60 - commits: 10 - linesAdded: 2647 - linesDeleted: 2416 - rank: 2 - newContributor: false - - username: som-snytt - gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 - commits: 9 - linesAdded: 662 - linesDeleted: 339 - rank: 3 - newContributor: false - - username: Ichoran - gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 - commits: 8 - linesAdded: 277 - linesDeleted: 75 - rank: 4 - newContributor: false - - username: pavelpavlov - gravatar: https://avatars0.githubusercontent.com/u/1330451?v=2&s=60 - commits: 3 - linesAdded: 44 - linesDeleted: 54 - rank: 5 - newContributor: false - - username: Blaisorblade - gravatar: https://avatars2.githubusercontent.com/u/289960?v=2&s=60 - commits: 3 - linesAdded: 6 - linesDeleted: 5 - rank: 5 - newContributor: false - - username: soc - gravatar: https://avatars0.githubusercontent.com/u/42493?v=2&s=60 - commits: 3 - linesAdded: 476 - linesDeleted: 338 - rank: 5 - newContributor: false - - username: gourlaysama - gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 - commits: 2 - linesAdded: 7 - linesDeleted: 7 - rank: 6 - newContributor: false - - username: greenrd - gravatar: https://avatars1.githubusercontent.com/u/164965?v=2&s=60 - commits: 1 - linesAdded: 2 - linesDeleted: 3 - rank: 7 - newContributor: false - - username: clhodapp - gravatar: https://avatars0.githubusercontent.com/u/108633?v=2&s=60 - commits: 1 - linesAdded: 228 - linesDeleted: 0 - rank: 7 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2014-04-01-scala-fame-2014-03.md b/contribute/scala-fame-data/_posts/2014-04-01-scala-fame-2014-03.md deleted file mode 100644 index 954a870612..0000000000 --- a/contribute/scala-fame-data/_posts/2014-04-01-scala-fame-2014-03.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -layout: famearchive -title: Contributors of March 2014 -fame-year: 2014 -fame-month: 3 -fame-month-str: March -fame-categories: - - category: Typesafe - authors: - - username: adriaanm - gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 - commits: 79 - linesAdded: 24547 - linesDeleted: 24999 - rank: 1 - newContributor: false - - username: retronym - gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 - commits: 21 - linesAdded: 622 - linesDeleted: 101 - rank: 2 - newContributor: false - - username: gkossakowski - gravatar: https://avatars0.githubusercontent.com/u/4217?v=2&s=60 - commits: 3 - linesAdded: 236 - linesDeleted: 6 - rank: 3 - newContributor: false - - username: huitseeker - gravatar: https://avatars2.githubusercontent.com/u/4142?v=2&s=60 - commits: 2 - linesAdded: 4 - linesDeleted: 2 - rank: 4 - newContributor: false - - username: szeiger - gravatar: https://avatars3.githubusercontent.com/u/54262?v=2&s=60 - commits: 1 - linesAdded: 8 - linesDeleted: 1 - rank: 5 - newContributor: false - - username: viktorklang - gravatar: https://avatars0.githubusercontent.com/u/10871?v=2&s=60 - commits: 1 - linesAdded: 7 - linesDeleted: 2 - rank: 5 - newContributor: false - - username: paulp - gravatar: https://avatars2.githubusercontent.com/u/9135?v=2&s=60 - commits: 1 - linesAdded: 20 - linesDeleted: 3 - rank: 5 - newContributor: false - - category: EPFL - authors: - - username: xeno-by - gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 - commits: 10 - linesAdded: 379 - linesDeleted: 76 - rank: 1 - newContributor: false - - category: Community - authors: - - username: densh - gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 - commits: 13 - linesAdded: 589 - linesDeleted: 115 - rank: 1 - newContributor: false - - username: som-snytt - gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 - commits: 4 - linesAdded: 31 - linesDeleted: 23 - rank: 2 - newContributor: false - - username: VladimirNik - gravatar: https://avatars2.githubusercontent.com/u/2835001?v=2&s=60 - commits: 2 - linesAdded: 1778 - linesDeleted: 1441 - rank: 3 - newContributor: false - - username: mkubala - gravatar: https://avatars0.githubusercontent.com/u/328844?v=2&s=60 - commits: 1 - linesAdded: 247 - linesDeleted: 53 - rank: 4 - newContributor: false - - username: puffnfresh - gravatar: https://avatars1.githubusercontent.com/u/37715?v=2&s=60 - commits: 1 - linesAdded: 0 - linesDeleted: 1 - rank: 4 - newContributor: false - - username: iainmcgin - gravatar: https://avatars0.githubusercontent.com/u/309153?v=2&s=60 - commits: 1 - linesAdded: 20 - linesDeleted: 19 - rank: 4 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2014-05-01-scala-fame-2014-04.md b/contribute/scala-fame-data/_posts/2014-05-01-scala-fame-2014-04.md deleted file mode 100644 index 66c6819f17..0000000000 --- a/contribute/scala-fame-data/_posts/2014-05-01-scala-fame-2014-04.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -layout: famearchive -title: Contributors of April 2014 -fame-year: 2014 -fame-month: 4 -fame-month-str: April -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 - commits: 9 - linesAdded: 177 - linesDeleted: 34 - rank: 1 - newContributor: false - - username: huitseeker - gravatar: https://avatars2.githubusercontent.com/u/4142?v=2&s=60 - commits: 1 - linesAdded: 16 - linesDeleted: 1 - rank: 2 - newContributor: false - - username: gkossakowski - gravatar: https://avatars0.githubusercontent.com/u/4217?v=2&s=60 - commits: 1 - linesAdded: 10 - linesDeleted: 3 - rank: 2 - newContributor: false - - username: adriaanm - gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 - commits: 1 - linesAdded: 34 - linesDeleted: 2 - rank: 2 - newContributor: false - - category: EPFL - authors: - - username: lrytz - gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 - commits: 2 - linesAdded: 202 - linesDeleted: 75 - rank: 1 - newContributor: false - - username: VladUreche - gravatar: https://avatars0.githubusercontent.com/u/428706?v=2&s=60 - commits: 1 - linesAdded: 24 - linesDeleted: 3 - rank: 2 - newContributor: false - - username: xeno-by - gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 - commits: 1 - linesAdded: 12 - linesDeleted: 1 - rank: 2 - newContributor: false - - category: Community - authors: - - username: gourlaysama - gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 - commits: 3 - linesAdded: 51 - linesDeleted: 5 - rank: 1 - newContributor: false - - username: som-snytt - gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 - commits: 2 - linesAdded: 110 - linesDeleted: 51 - rank: 2 - newContributor: false - - username: lefou - gravatar: https://avatars2.githubusercontent.com/u/1321393?v=2&s=60 - commits: 1 - linesAdded: 45 - linesDeleted: 8 - rank: 3 - newContributor: false - - username: densh - gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 - commits: 1 - linesAdded: 4 - linesDeleted: 5 - rank: 3 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2014-06-01-scala-fame-2014-05.md b/contribute/scala-fame-data/_posts/2014-06-01-scala-fame-2014-05.md deleted file mode 100644 index f9191afb17..0000000000 --- a/contribute/scala-fame-data/_posts/2014-06-01-scala-fame-2014-05.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -layout: famearchive -title: Contributors of May 2014 -fame-year: 2014 -fame-month: 5 -fame-month-str: May -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 - commits: 32 - linesAdded: 951 - linesDeleted: 136 - rank: 1 - newContributor: false - - username: adriaanm - gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 - commits: 9 - linesAdded: 21 - linesDeleted: 70 - rank: 2 - newContributor: false - - username: gkossakowski - gravatar: https://avatars0.githubusercontent.com/u/4217?v=2&s=60 - commits: 3 - linesAdded: 13 - linesDeleted: 18 - rank: 3 - newContributor: false - - category: EPFL - authors: - - username: lrytz - gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 - commits: 23 - linesAdded: 6048 - linesDeleted: 2325 - rank: 1 - newContributor: false - - username: xeno-by - gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 - commits: 3 - linesAdded: 93 - linesDeleted: 3 - rank: 2 - newContributor: false - - category: Community - authors: - - username: som-snytt - gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 - commits: 12 - linesAdded: 442 - linesDeleted: 238 - rank: 1 - newContributor: false - - username: lefou - gravatar: https://avatars2.githubusercontent.com/u/1321393?v=2&s=60 - commits: 3 - linesAdded: 14 - linesDeleted: 24 - rank: 2 - newContributor: false - - username: tvierling - gravatar: https://avatars3.githubusercontent.com/u/397857?v=2&s=60 - commits: 2 - linesAdded: 35 - linesDeleted: 11 - rank: 3 - newContributor: true - - username: clhodapp - gravatar: https://avatars0.githubusercontent.com/u/108633?v=2&s=60 - commits: 2 - linesAdded: 98 - linesDeleted: 51 - rank: 3 - newContributor: false - - username: Ichoran - gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 - commits: 2 - linesAdded: 55 - linesDeleted: 16 - rank: 3 - newContributor: false - - username: mkubala - gravatar: https://avatars0.githubusercontent.com/u/328844?v=2&s=60 - commits: 1 - linesAdded: 1 - linesDeleted: 0 - rank: 4 - newContributor: false - - username: jedesah - gravatar: https://avatars1.githubusercontent.com/u/1780116?v=2&s=60 - commits: 1 - linesAdded: 23 - linesDeleted: 1 - rank: 4 - newContributor: false - - username: VladimirNik - gravatar: https://avatars2.githubusercontent.com/u/2835001?v=2&s=60 - commits: 1 - linesAdded: 78 - linesDeleted: 40 - rank: 4 - newContributor: false - - username: densh - gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 - commits: 1 - linesAdded: 14 - linesDeleted: 0 - rank: 4 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2014-07-01-scala-fame-2014-06.md b/contribute/scala-fame-data/_posts/2014-07-01-scala-fame-2014-06.md deleted file mode 100644 index 5f051d08a7..0000000000 --- a/contribute/scala-fame-data/_posts/2014-07-01-scala-fame-2014-06.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -layout: famearchive -title: Contributors of June 2014 -fame-year: 2014 -fame-month: 6 -fame-month-str: June -fame-categories: - - category: Typesafe - authors: - - username: adriaanm - gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 - commits: 14 - linesAdded: 873 - linesDeleted: 661 - rank: 1 - newContributor: false - - username: retronym - gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 - commits: 8 - linesAdded: 166 - linesDeleted: 126 - rank: 2 - newContributor: false - - category: EPFL - authors: - - username: lrytz - gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 - commits: 16 - linesAdded: 1865 - linesDeleted: 437 - rank: 1 - newContributor: false - - username: xeno-by - gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 - commits: 4 - linesAdded: 164 - linesDeleted: 44 - rank: 2 - newContributor: false - - username: odersky - gravatar: https://avatars2.githubusercontent.com/u/795990?v=2&s=60 - commits: 1 - linesAdded: 36 - linesDeleted: 10 - rank: 3 - newContributor: false - - category: Community - authors: - - username: Ichoran - gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 - commits: 7 - linesAdded: 275 - linesDeleted: 57 - rank: 1 - newContributor: false - - username: jxcoder - gravatar: https://avatars1.githubusercontent.com/u/1075547?v=2&s=60 - commits: 4 - linesAdded: 41 - linesDeleted: 19 - rank: 2 - newContributor: true - - username: gourlaysama - gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 - commits: 2 - linesAdded: 20 - linesDeleted: 6 - rank: 3 - newContributor: false - - username: som-snytt - gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 - commits: 2 - linesAdded: 146 - linesDeleted: 41 - rank: 3 - newContributor: false - - username: jrudolph - gravatar: https://avatars1.githubusercontent.com/u/9868?v=2&s=60 - commits: 1 - linesAdded: 97 - linesDeleted: 4 - rank: 4 - newContributor: false - - username: Blaisorblade - gravatar: https://avatars2.githubusercontent.com/u/289960?v=2&s=60 - commits: 1 - linesAdded: 6 - linesDeleted: 1 - rank: 4 - newContributor: false - - username: densh - gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 - commits: 1 - linesAdded: 17 - linesDeleted: 5 - rank: 4 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2014-08-01-scala-fame-2014-07.md b/contribute/scala-fame-data/_posts/2014-08-01-scala-fame-2014-07.md deleted file mode 100644 index c57474778d..0000000000 --- a/contribute/scala-fame-data/_posts/2014-08-01-scala-fame-2014-07.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -layout: famearchive -title: Contributors of July 2014 -fame-year: 2014 -fame-month: 7 -fame-month-str: July -fame-categories: - - category: Typesafe - authors: - - username: adriaanm - gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 - commits: 31 - linesAdded: 775 - linesDeleted: 712 - rank: 1 - newContributor: false - - username: phaller - gravatar: https://avatars0.githubusercontent.com/u/289943?v=2&s=60 - commits: 3 - linesAdded: 161 - linesDeleted: 49 - rank: 2 - newContributor: false - - username: retronym - gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 - commits: 1 - linesAdded: 35 - linesDeleted: 34 - rank: 3 - newContributor: false - - category: EPFL - authors: - - username: lrytz - gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 - commits: 4 - linesAdded: 84 - linesDeleted: 29 - rank: 1 - newContributor: false - - category: Community - authors: - - username: som-snytt - gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 - commits: 11 - linesAdded: 330 - linesDeleted: 226 - rank: 1 - newContributor: false - - username: gourlaysama - gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 - commits: 5 - linesAdded: 217 - linesDeleted: 94 - rank: 2 - newContributor: false - - username: dhgarrette - gravatar: https://avatars2.githubusercontent.com/u/484190?v=2&s=60 - commits: 2 - linesAdded: 1 - linesDeleted: 3 - rank: 3 - newContributor: true - - username: pocket7878 - gravatar: https://avatars1.githubusercontent.com/u/236528?v=2&s=60 - commits: 2 - linesAdded: 21 - linesDeleted: 13 - rank: 3 - newContributor: true - - username: dgruntz - gravatar: https://avatars3.githubusercontent.com/u/1516800?v=2&s=60 - commits: 2 - linesAdded: 4 - linesDeleted: 4 - rank: 3 - newContributor: false - - username: Ichoran - gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 - commits: 1 - linesAdded: 26 - linesDeleted: 9 - rank: 4 - newContributor: false - - username: kzys - gravatar: https://avatars2.githubusercontent.com/u/19111?v=2&s=60 - commits: 1 - linesAdded: 19 - linesDeleted: 0 - rank: 4 - newContributor: false - - username: densh - gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 - commits: 1 - linesAdded: 3 - linesDeleted: 1 - rank: 4 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2014-09-01-scala-fame-2014-08.md b/contribute/scala-fame-data/_posts/2014-09-01-scala-fame-2014-08.md deleted file mode 100644 index afef86d3be..0000000000 --- a/contribute/scala-fame-data/_posts/2014-09-01-scala-fame-2014-08.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -layout: famearchive -title: Contributors of August 2014 -fame-year: 2014 -fame-month: 8 -fame-month-str: August -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 - commits: 3 - linesAdded: 57 - linesDeleted: 4 - rank: 1 - newContributor: false - - username: adriaanm - gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 - commits: 2 - linesAdded: 57 - linesDeleted: 42 - rank: 2 - newContributor: false - - category: EPFL - authors: - - username: lrytz - gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 - commits: 21 - linesAdded: 3764 - linesDeleted: 2122 - rank: 1 - newContributor: false - - category: Community - authors: - - username: gourlaysama - gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 - commits: 10 - linesAdded: 171 - linesDeleted: 7680 - rank: 1 - newContributor: false - - username: som-snytt - gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 - commits: 10 - linesAdded: 917 - linesDeleted: 543 - rank: 1 - newContributor: false - - username: gbasler - gravatar: https://avatars1.githubusercontent.com/u/273035?v=2&s=60 - commits: 1 - linesAdded: 14 - linesDeleted: 22 - rank: 2 - newContributor: false - - username: dgruntz - gravatar: https://avatars3.githubusercontent.com/u/1516800?v=2&s=60 - commits: 1 - linesAdded: 18 - linesDeleted: 18 - rank: 2 - newContributor: false - - username: Ichoran - gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 - commits: 1 - linesAdded: 26 - linesDeleted: 27 - rank: 2 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2014-10-01-scala-fame-2014-09.md b/contribute/scala-fame-data/_posts/2014-10-01-scala-fame-2014-09.md deleted file mode 100644 index ee67016186..0000000000 --- a/contribute/scala-fame-data/_posts/2014-10-01-scala-fame-2014-09.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -layout: famearchive -title: Contributors of September 2014 -fame-year: 2014 -fame-month: 9 -fame-month-str: September -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 - commits: 12 - linesAdded: 182 - linesDeleted: 23 - rank: 1 - newContributor: false - - username: dragos - gravatar: https://avatars2.githubusercontent.com/u/133742?v=2&s=60 - commits: 1 - linesAdded: 169 - linesDeleted: 169 - rank: 2 - newContributor: false - - category: EPFL - authors: - - username: lrytz - gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 - commits: 6 - linesAdded: 262 - linesDeleted: 85 - rank: 1 - newContributor: false - - username: xeno-by - gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 - commits: 3 - linesAdded: 1272 - linesDeleted: 1240 - rank: 2 - newContributor: false - - category: Community - authors: - - username: gourlaysama - gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 - commits: 9 - linesAdded: 1782 - linesDeleted: 1227 - rank: 1 - newContributor: false - - username: som-snytt - gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 - commits: 4 - linesAdded: 305 - linesDeleted: 125 - rank: 2 - newContributor: false - - username: puffnfresh - gravatar: https://avatars1.githubusercontent.com/u/37715?v=2&s=60 - commits: 3 - linesAdded: 42 - linesDeleted: 7 - rank: 3 - newContributor: false - - username: Ichoran - gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 - commits: 2 - linesAdded: 12 - linesDeleted: 1 - rank: 4 - newContributor: false - - username: gbasler - gravatar: https://avatars1.githubusercontent.com/u/273035?v=2&s=60 - commits: 1 - linesAdded: 115 - linesDeleted: 41 - rank: 5 - newContributor: false - - username: soc - gravatar: https://avatars0.githubusercontent.com/u/42493?v=2&s=60 - commits: 1 - linesAdded: 4 - linesDeleted: 1 - rank: 5 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2014-11-01-scala-fame-2014-10.md b/contribute/scala-fame-data/_posts/2014-11-01-scala-fame-2014-10.md deleted file mode 100644 index 0c957577fb..0000000000 --- a/contribute/scala-fame-data/_posts/2014-11-01-scala-fame-2014-10.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -layout: famearchive -title: Contributors of October 2014 -fame-year: 2014 -fame-month: 10 -fame-month-str: October -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 - commits: 11 - linesAdded: 414 - linesDeleted: 51 - rank: 1 - newContributor: false - - username: gkossakowski - gravatar: https://avatars0.githubusercontent.com/u/4217?v=2&s=60 - commits: 2 - linesAdded: 2 - linesDeleted: 2 - rank: 2 - newContributor: false - - username: adriaanm - gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 - commits: 2 - linesAdded: 54 - linesDeleted: 18 - rank: 2 - newContributor: false - - category: EPFL - authors: - - username: lrytz - gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 - commits: 4 - linesAdded: 146 - linesDeleted: 171 - rank: 1 - newContributor: false - - category: Community - authors: - - username: roberthoedicke - gravatar: https://avatars0.githubusercontent.com/u/9093826?v=2&s=60 - commits: 9 - linesAdded: 15 - linesDeleted: 15 - rank: 1 - newContributor: true - - username: puffnfresh - gravatar: https://avatars1.githubusercontent.com/u/37715?v=2&s=60 - commits: 1 - linesAdded: 19 - linesDeleted: 10 - rank: 2 - newContributor: false - - username: Blaisorblade - gravatar: https://avatars2.githubusercontent.com/u/289960?v=2&s=60 - commits: 1 - linesAdded: 0 - linesDeleted: 93 - rank: 2 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2014-12-01-scala-fame-2014-11.md b/contribute/scala-fame-data/_posts/2014-12-01-scala-fame-2014-11.md deleted file mode 100644 index 3c95eb2521..0000000000 --- a/contribute/scala-fame-data/_posts/2014-12-01-scala-fame-2014-11.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -layout: famearchive -title: Contributors of November 2014 -fame-year: 2014 -fame-month: 11 -fame-month-str: November -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://avatars1.githubusercontent.com/u/65551?v=3&s=60 - commits: 24 - linesAdded: 650 - linesDeleted: 90 - rank: 1 - newContributor: false - - username: adriaanm - gravatar: https://avatars3.githubusercontent.com/u/91083?v=3&s=60 - commits: 3 - linesAdded: 208 - linesDeleted: 54 - rank: 2 - newContributor: false - - username: phaller - gravatar: https://avatars1.githubusercontent.com/u/289943?v=3&s=60 - commits: 1 - linesAdded: 10 - linesDeleted: 8 - rank: 3 - newContributor: false - - category: EPFL - authors: - - username: lrytz - gravatar: https://avatars2.githubusercontent.com/u/119636?v=3&s=60 - commits: 6 - linesAdded: 782 - linesDeleted: 32 - rank: 1 - newContributor: false - - username: heathermiller - gravatar: https://avatars1.githubusercontent.com/u/687163?v=3&s=60 - commits: 2 - linesAdded: 64 - linesDeleted: 66 - rank: 2 - newContributor: false - - category: Community - authors: - - username: gourlaysama - gravatar: https://avatars3.githubusercontent.com/u/733438?v=3&s=60 - commits: 7 - linesAdded: 245 - linesDeleted: 83 - rank: 1 - newContributor: false - - username: som-snytt - gravatar: https://avatars3.githubusercontent.com/u/369425?v=3&s=60 - commits: 3 - linesAdded: 53 - linesDeleted: 53 - rank: 2 - newContributor: false - - username: advancedxy - gravatar: https://avatars1.githubusercontent.com/u/807537?v=3&s=60 - commits: 2 - linesAdded: 2 - linesDeleted: 2 - rank: 3 - newContributor: true - - username: kanielc - gravatar: https://avatars1.githubusercontent.com/u/1334074?v=3&s=60 - commits: 2 - linesAdded: 3 - linesDeleted: 3 - rank: 3 - newContributor: true - - username: gdickinson - gravatar: https://avatars3.githubusercontent.com/u/1130928?v=3&s=60 - commits: 2 - linesAdded: 0 - linesDeleted: 380 - rank: 3 - newContributor: true - - username: Ichoran - gravatar: https://avatars2.githubusercontent.com/u/2298644?v=3&s=60 - commits: 2 - linesAdded: 35 - linesDeleted: 18 - rank: 3 - newContributor: false - - username: ruippeixotog - gravatar: https://avatars1.githubusercontent.com/u/613493?v=3&s=60 - commits: 1 - linesAdded: 81 - linesDeleted: 8 - rank: 4 - newContributor: false - - username: mpociecha - gravatar: https://avatars0.githubusercontent.com/u/6143494?v=3&s=60 - commits: 1 - linesAdded: 5 - linesDeleted: 2 - rank: 4 - newContributor: false - - username: soc - gravatar: https://avatars1.githubusercontent.com/u/42493?v=3&s=60 - commits: 1 - linesAdded: 1 - linesDeleted: 1 - rank: 4 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2015-01-01-scala-fame-2014-12.md b/contribute/scala-fame-data/_posts/2015-01-01-scala-fame-2014-12.md deleted file mode 100644 index c11348b33a..0000000000 --- a/contribute/scala-fame-data/_posts/2015-01-01-scala-fame-2014-12.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -layout: famearchive -title: Contributors of December 2014 -fame-year: 2014 -fame-month: 12 -fame-month-str: December -fame-categories: - - category: Typesafe - authors: - - username: adriaanm - gravatar: https://avatars3.githubusercontent.com/u/91083?v=3&s=60 - commits: 2 - linesAdded: 962 - linesDeleted: 290 - rank: 1 - newContributor: false - - username: retronym - gravatar: https://avatars1.githubusercontent.com/u/65551?v=3&s=60 - commits: 1 - linesAdded: 5 - linesDeleted: 1 - rank: 2 - newContributor: false - - category: EPFL - authors: - - username: lrytz - gravatar: https://avatars2.githubusercontent.com/u/119636?v=3&s=60 - commits: 4 - linesAdded: 61 - linesDeleted: 50 - rank: 1 - newContributor: false - - category: Community - authors: - - username: gbasler - gravatar: https://avatars0.githubusercontent.com/u/273035?v=3&s=60 - commits: 2 - linesAdded: 567 - linesDeleted: 1 - rank: 1 - newContributor: false - - username: kanielc - gravatar: https://avatars1.githubusercontent.com/u/1334074?v=3&s=60 - commits: 1 - linesAdded: 43 - linesDeleted: 6 - rank: 2 - newContributor: false - - username: xuwei-k - gravatar: https://avatars2.githubusercontent.com/u/389787?v=3&s=60 - commits: 1 - linesAdded: 2 - linesDeleted: 2 - rank: 2 - newContributor: false - - username: gourlaysama - gravatar: https://avatars3.githubusercontent.com/u/733438?v=3&s=60 - commits: 1 - linesAdded: 1 - linesDeleted: 1 - rank: 2 - newContributor: false - - username: som-snytt - gravatar: https://avatars3.githubusercontent.com/u/369425?v=3&s=60 - commits: 1 - linesAdded: 44 - linesDeleted: 3 - rank: 2 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2015-02-01-scala-fame-2015-01.md b/contribute/scala-fame-data/_posts/2015-02-01-scala-fame-2015-01.md deleted file mode 100644 index 4af6e3d778..0000000000 --- a/contribute/scala-fame-data/_posts/2015-02-01-scala-fame-2015-01.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -layout: famearchive -title: Contributors of January 2015 -fame-year: 2015 -fame-month: 1 -fame-month-str: January -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://avatars1.githubusercontent.com/u/65551?v=3&s=60 - commits: 10 - linesAdded: 222 - linesDeleted: 26 - rank: 1 - newContributor: false - - username: adriaanm - gravatar: https://avatars3.githubusercontent.com/u/91083?v=3&s=60 - commits: 4 - linesAdded: 819 - linesDeleted: 636 - rank: 2 - newContributor: false - - category: EPFL - authors: - - username: lrytz - gravatar: https://avatars2.githubusercontent.com/u/119636?v=3&s=60 - commits: 4 - linesAdded: 470 - linesDeleted: 152 - rank: 1 - newContributor: false - - category: Community - authors: - - username: kanielc - gravatar: https://avatars1.githubusercontent.com/u/1334074?v=3&s=60 - commits: 2 - linesAdded: 58 - linesDeleted: 2 - rank: 1 - newContributor: false - - username: som-snytt - gravatar: https://avatars3.githubusercontent.com/u/369425?v=3&s=60 - commits: 2 - linesAdded: 35 - linesDeleted: 41 - rank: 1 - newContributor: false - - username: dickwall - gravatar: https://avatars2.githubusercontent.com/u/56453?v=3&s=60 - commits: 1 - linesAdded: 74 - linesDeleted: 0 - rank: 2 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2015-03-01-scala-fame-2015-02.md b/contribute/scala-fame-data/_posts/2015-03-01-scala-fame-2015-02.md deleted file mode 100644 index 3fe846623b..0000000000 --- a/contribute/scala-fame-data/_posts/2015-03-01-scala-fame-2015-02.md +++ /dev/null @@ -1,70 +0,0 @@ ---- -layout: famearchive -title: Contributors of February 2015 -fame-year: 2015 -fame-month: 2 -fame-month-str: February -fame-categories: - - category: Typesafe - authors: - - username: adriaanm - gravatar: https://avatars3.githubusercontent.com/u/91083?v=3&s=60 - commits: 15 - linesAdded: 1199 - linesDeleted: 588 - rank: 1 - newContributor: false - - username: retronym - gravatar: https://avatars1.githubusercontent.com/u/65551?v=3&s=60 - commits: 13 - linesAdded: 557 - linesDeleted: 64 - rank: 2 - newContributor: false - - category: EPFL - authors: - - username: lrytz - gravatar: https://avatars2.githubusercontent.com/u/119636?v=3&s=60 - commits: 10 - linesAdded: 1629 - linesDeleted: 276 - rank: 1 - newContributor: false - - username: xeno-by - gravatar: https://avatars0.githubusercontent.com/u/609152?v=3&s=60 - commits: 2 - linesAdded: 108 - linesDeleted: 15 - rank: 2 - newContributor: false - - username: axel22 - gravatar: https://avatars0.githubusercontent.com/u/151774?v=3&s=60 - commits: 1 - linesAdded: 61 - linesDeleted: 0 - rank: 3 - newContributor: false - - category: Community - authors: - - username: Ichoran - gravatar: https://avatars2.githubusercontent.com/u/2298644?v=3&s=60 - commits: 3 - linesAdded: 62 - linesDeleted: 25 - rank: 1 - newContributor: false - - username: som-snytt - gravatar: https://avatars3.githubusercontent.com/u/369425?v=3&s=60 - commits: 2 - linesAdded: 121 - linesDeleted: 30 - rank: 2 - newContributor: false - - username: milessabin - gravatar: https://avatars1.githubusercontent.com/u/131183?v=3&s=60 - commits: 1 - linesAdded: 123 - linesDeleted: 37 - rank: 3 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2015-04-01-scala-fame-2015-03.md b/contribute/scala-fame-data/_posts/2015-04-01-scala-fame-2015-03.md deleted file mode 100644 index 62e7ea2f58..0000000000 --- a/contribute/scala-fame-data/_posts/2015-04-01-scala-fame-2015-03.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -layout: famearchive -title: Contributors of March 2015 -fame-year: 2015 -fame-month: 3 -fame-month-str: March -fame-categories: - - category: Typesafe - authors: - - username: retronym - gravatar: https://avatars1.githubusercontent.com/u/65551?v=3&s=60 - commits: 9 - linesAdded: 553 - linesDeleted: 27 - rank: 1 - newContributor: false - - username: adriaanm - gravatar: https://avatars3.githubusercontent.com/u/91083?v=3&s=60 - commits: 6 - linesAdded: 12 - linesDeleted: 72 - rank: 2 - newContributor: false - - category: EPFL - authors: - - username: lrytz - gravatar: https://avatars2.githubusercontent.com/u/119636?v=3&s=60 - commits: 18 - linesAdded: 2857 - linesDeleted: 916 - rank: 1 - newContributor: false - - username: xeno-by - gravatar: https://avatars0.githubusercontent.com/u/609152?v=3&s=60 - commits: 1 - linesAdded: 7 - linesDeleted: 5 - rank: 2 - newContributor: false - - category: Community - authors: - - username: gourlaysama - gravatar: https://avatars3.githubusercontent.com/u/733438?v=3&s=60 - commits: 4 - linesAdded: 132 - linesDeleted: 22 - rank: 1 - newContributor: false - - username: gbasler - gravatar: https://avatars0.githubusercontent.com/u/273035?v=3&s=60 - commits: 3 - linesAdded: 1986 - linesDeleted: 111 - rank: 2 - newContributor: false - - username: kzys - gravatar: https://avatars3.githubusercontent.com/u/19111?v=3&s=60 - commits: 2 - linesAdded: 37 - linesDeleted: 18 - rank: 3 - newContributor: false - - username: som-snytt - gravatar: https://avatars3.githubusercontent.com/u/369425?v=3&s=60 - commits: 2 - linesAdded: 91 - linesDeleted: 7 - rank: 3 - newContributor: false - - username: sschaef - gravatar: https://avatars3.githubusercontent.com/u/488530?v=3&s=60 - commits: 1 - linesAdded: 1 - linesDeleted: 1 - rank: 4 - newContributor: false - - username: khernyo - gravatar: https://avatars2.githubusercontent.com/u/447532?v=3&s=60 - commits: 1 - linesAdded: 27 - linesDeleted: 8 - rank: 4 - newContributor: false - - username: soc - gravatar: https://avatars1.githubusercontent.com/u/42493?v=3&s=60 - commits: 1 - linesAdded: 7 - linesDeleted: 7 - rank: 4 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2015-11-01-scala-fame-2015-10.md b/contribute/scala-fame-data/_posts/2015-11-01-scala-fame-2015-10.md deleted file mode 100644 index 41698296db..0000000000 --- a/contribute/scala-fame-data/_posts/2015-11-01-scala-fame-2015-10.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -layout: famearchive -title: Contributors of October 2015 -fame-year: 2015 -fame-month: 10 -fame-month-str: October -fame-categories: - - category: Typesafe - authors: - - username: SethTisue - gravatar: https://avatars.githubusercontent.com/u/161079?v=3 - commits: 9 - linesAdded: 80 - linesDeleted: 55 - rank: 1 - newContributor: false - - category: EPFL - authors: - - username: sjrd - gravatar: https://avatars.githubusercontent.com/u/535934?v=3 - commits: 1 - linesAdded: 1 - linesDeleted: 4 - rank: 1 - newContributor: false - - category: Community - authors: - - username: performantdata - gravatar: https://avatars.githubusercontent.com/u/6363453?v=3 - commits: 6 - linesAdded: 97 - linesDeleted: 50 - rank: 1 - newContributor: true - - username: janekdb - gravatar: https://avatars.githubusercontent.com/u/1123855?v=3 - commits: 1 - linesAdded: 86 - linesDeleted: 71 - rank: 2 - newContributor: false ---- diff --git a/contribute/scala-fame-data/_posts/2015-12-01-scala-fame-2015-11.md b/contribute/scala-fame-data/_posts/2015-12-01-scala-fame-2015-11.md deleted file mode 100644 index 8f9b7ff3b1..0000000000 --- a/contribute/scala-fame-data/_posts/2015-12-01-scala-fame-2015-11.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -layout: famearchive -title: Contributors of November 2015 -fame-year: 2015 -fame-month: 11 -fame-month-str: November -fame-categories: - - category: Typesafe - authors: - - username: szeiger - gravatar: https://avatars.githubusercontent.com/u/54262?v=3 - commits: 5 - linesAdded: 427 - linesDeleted: 116 - rank: 1 - newContributor: false - - username: SethTisue - gravatar: https://avatars.githubusercontent.com/u/161079?v=3 - commits: 3 - linesAdded: 21 - linesDeleted: 21 - rank: 2 - newContributor: false - - username: retronym - gravatar: https://avatars.githubusercontent.com/u/65551?v=3 - commits: 3 - linesAdded: 44 - linesDeleted: 28 - rank: 2 - newContributor: false - - username: adriaanm - gravatar: https://avatars.githubusercontent.com/u/91083?v=3 - commits: 2 - linesAdded: 22 - linesDeleted: 25 - rank: 3 - newContributor: false - - username: lrytz - gravatar: https://avatars.githubusercontent.com/u/119636?v=3 - commits: 1 - linesAdded: 7 - linesDeleted: 18 - rank: 4 - newContributor: false - - category: EPFL - authors: - - category: Community - authors: - - username: janekdb - gravatar: https://avatars.githubusercontent.com/u/1123855?v=3 - commits: 6 - linesAdded: 76 - linesDeleted: 63 - rank: 1 - newContributor: false - - username: soc - gravatar: https://avatars.githubusercontent.com/u/42493?v=3 - commits: 2 - linesAdded: 14 - linesDeleted: 19 - rank: 2 - newContributor: false ---- diff --git a/contribute/scala-fame.md b/contribute/scala-fame.md deleted file mode 100644 index 4b6591004a..0000000000 --- a/contribute/scala-fame.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -layout: page-full-width -title: Scala Contributor Hall of Fame ---- - -A big thank you to everyone who has contributed over the years to: - - - [the Scala library and compiler](https://github.com/scala/scala/contributors) - - [the Scala documentation website](https://github.com/scala/scala.github.com/contributors) - -What follows are the commit totals, to the 2.12.x branch of the scala/scala repo only, -for last month. (For a commit to be counted, it must have been both committed and merged -in the same month.) - -For a more detailed view of recent activity, see the repo's -[GitHub Pulse page](https://github.com/scala/scala/pulse/monthly). - -{% for data in site.categories.scala-fame-data limit:1 %} - {% assign famedata = data %} - {% include render-scala-fame.html %} -{% endfor %} From 76fa6b98681ed1603718b99c6c20ec003b11025b Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Wed, 24 Feb 2016 16:48:19 -0500 Subject: [PATCH 0094/3075] Typesafe -> Lightbend in a bunch of places --- contribute/documentation.md | 4 ++-- contribute/guide.md | 2 +- contribute/hacker-guide.md | 2 +- contribute/index.md | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contribute/documentation.md b/contribute/documentation.md index d7597d8884..6b5c81a0fc 100644 --- a/contribute/documentation.md +++ b/contribute/documentation.md @@ -30,10 +30,10 @@ without creating an issue, but please look to see if there is an issue already s ### Examples/Tutorials in Activator Templates -[Typesafe Activator](https://typesafe.com/community/core-tools/activator-and-sbt) +[Lightbend Activator](https://www.lightbend.com/community/core-tools/activator-and-sbt) is a tool based on SBT, with a UI mode that is ideal for code based tutorials, overviews and walk-throughs. To contribute an example in activator, you can fork an existing template, edit it, add a tutorial, upload it to github and then submit the github project into the template repository. It's the fastest way to produce a working code example with tutorial. -Please see [Contributing an Activator Template](https://typesafe.com/activator/template/contribute) for more details. +Please see [Contributing an Activator Template](https://www.lightbend.com/activator/template/contribute) for more details. ### The Main Scala Documentation Site diff --git a/contribute/guide.md b/contribute/guide.md index 148ceb7570..b92bd2fe89 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -44,7 +44,7 @@ Typically the scaladoc tool provides a low entry point for new committers, so it On the Scala bug tracker you will find many bugs that are [marked as good starting points to contributing ("community" bugs)](https://issues.scala-lang.org/secure/IssueNavigator.jspa?requestId=12111) or [that are not currently assigned](https://issues.scala-lang.org/secure/IssueNavigator.jspa?requestId=12112) and that you could pick up. Once you decided on a ticket to look at, see the next step on how to proceed further. If you are interested in contributing code, we ask you to sign the -[Scala Contributor License Agreement](http://typesafe.com/contribute/cla/scala), +[Scala Contributor License Agreement](http://www.lightbend.com/contribute/cla/scala), which allows us to ensure that all code submitted to the project is unencumbered by copyrights or patents. diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index fb79d8166d..47ebafe634 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -402,7 +402,7 @@ Once you are satisfied with your work, synced with `master` and cleaned up your Now, we must simply submit our proposed patch. Navigate to your branch in GitHub (for me it was `https://github.com/xeno-by/scala/tree/ticket/6725`) and click the pull request button to submit your patch as a pull request to Scala. If you've never submitted patches to Scala, you will -need to sign the contributor license agreement, which [can be done online](http://typesafe.com/contribute/cla/scala) within a few minutes. +need to sign the contributor license agreement, which [can be done online](http://www.lightbend.com/contribute/cla/scala) within a few minutes. Submit a pull request diff --git a/contribute/index.md b/contribute/index.md index 137838aba4..925e83248e 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -27,7 +27,7 @@ Coordination of contribution efforts takes place on the
@@ -119,7 +119,7 @@ to build and test a corpus of Scala open source projects against development versions of the Scala compiler and standard library in order to discover regressions prior to releases. -The build uses Typesafe's +The build uses Lightbend's [dbuild](https://github.com/typesafehub/dbuild) tool, which leverages [sbt](http://www.scala-sbt.org). From 55dfcf608ea8e8fd8a648ffa99ee9ccf45ae0486 Mon Sep 17 00:00:00 2001 From: Chase Long Date: Mon, 6 Jun 2016 21:12:56 -0500 Subject: [PATCH 0095/3075] Replace references to ant with corresponding sbt references --- contribute/hacker-guide.md | 105 ++++++++++--------------------------- 1 file changed, 29 insertions(+), 76 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 47ebafe634..dab991eba5 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -100,47 +100,25 @@ If you are new to Git and branching, read the [Branching Chapter](http://git-scm The next step after cloning your fork is setting up your machine to build Scala. -* It is recommended to use Java `1.6` (not `1.7` or `1.8`, because they might cause occasional glitches). -* The build tool is `ant`. If you are behind a HTTP proxy, include [`ANT_ARGS=-autoproxy`](https://ant.apache.org/manual/proxy.html) in your environment. -* The build runs the `pull-binary-libs.sh` script to download bootstrap libs. This requires `bash` and `curl`. -* The majority of our team works on Linux and OS X, so these operating systems are guaranteed to work. -* Windows is supported, but it might have issues. Please report to [the issue tracker](https://issues.scala-lang.org/) if you encounter any. +You need the following tools: -Building Scala is as easy as running `ant` in the root of your cloned repository. Be prepared to wait for a while-- a full "clean" build -takes 8+ minutes depending on your machine (and up to 30 minutes on older machines with less memory). Incremental builds are usually within 30-120 seconds range (again, your mileage might vary -with your hardware). - - 16:50 ~/Projects/scala (ticket/6725)$ ant - Buildfile: /Users/xeno_by/Projects/scala/build.xml - - strap.clean: - - pack.clean: - - init.jars.check: - - init.jars: - [echo] Updating bootstrap libs. (To do this by hand, run ./pull-binary-libs.sh) - [exec] Resolving [943cd5c8802b2a3a64a010efb86ec19bac142e40/lib/ant/ant-contrib.jar] - - ... - - pack.bin: - [mkdir] Created dir: /Users/xeno_by/Projects/scala/build/pack/bin +* A Java SDK. The baseline version is 6 for 2.11.x and 8 for 2.12.x. It's possible to use a later SDK for local development, but the continuous integration builds will verify against the baseline version. +* `sbt`, an interactive build tool commonly used in Scala projects. Acquiring sbt manually is not necessary -- the recommended approach is to download the [sbt-extras runner script](https://github.com/paulp/sbt-extras/blob/master/sbt) and use it in place of `sbt`. The script will download and run the correct version of sbt when run from the Scala repository's root directory. +* `curl` -- the build uses `curl` in the `pull-binary-libs.sh` script to download bootstrap libs. - pack.done: +The majority of our team works on Linux and OS X, so these operating systems are guaranteed to work. Windows is supported, but it might have issues. Please report to [the issue tracker](https://issues.scala-lang.org/) if you encounter any. - build: - - BUILD SUCCESSFUL - Total time: 9 minutes 41 seconds +Building Scala is as easy as running `sbt dist/mkPack` in the root of your cloned repository. Be prepared to wait for a while -- a full "clean" build +takes 8+ minutes depending on your machine (and up to 30 minutes on older machines with less memory). Incremental builds are usually within 30-120 seconds range (again, your mileage might vary +with your hardware). ### IDE There's no single editor of choice for working with Scala sources, as there are trade-offs associated with each available tool. Both Eclipse and IntelliJ IDEA have Scala plugins, which are known to work with our codebase. -Both of those Scala plugins provide navigation, refactoring and error reporting functionality as well as integrated debugging. +Both of those Scala plugins provide navigation, refactoring, error reporting functionality, and integrated debugging. +See [the Scala README](https://github.com/scala/scala#ide-setup) for instructions on using Eclipse and IntelliJ IDEA with the Scala repository. There also exist lighter-weight editors such as Emacs, Sublime or jEdit which are faster and much less memory/compute-intensive to run, while lacking semantic services and debugging. To address this shortcoming, they can integrate with ENSIME, @@ -155,8 +133,8 @@ When hacking on your topic of choice, you'll be modifying Scala, compiling it an Typically you would want to first make sure that your changes work on a small example and afterwards verify that nothing break by running a comprehensive test suite. -We'll start by creating a `sandbox` directory (this particular name doesn't bear any special meaning), which will hold a single test file and its compilation results. First, let's make sure that -[the bug](https://issues.scala-lang.org/browse/SI-6725) is indeed reproducible by putting together a simple test and compiling and running it with the Scala compiler that we built using `ant`. The Scala compiler that we just built is located in `build/pack/bin`. +We'll start by creating a `sandbox` directory (`./sandbox is listed in the .gitignore of the Scala repository), which will hold a single test file and its compilation results. First, let's make sure that +[the bug](https://issues.scala-lang.org/browse/SI-6725) is indeed reproducible by putting together a simple test and compiling and running it with the Scala compiler that we built using `sbt`. The Scala compiler that we just built is located in `build/pack/bin`. 17:25 ~/Projects/scala (ticket/6725)$ mkdir sandbox 17:26 ~/Projects/scala (ticket/6725)$ cd sandbox @@ -178,31 +156,24 @@ Now, implement your bugfix or new feature! Here are also some tips & tricks that have proven useful in Scala development: * If after introducing changes or updating your clone, you get `AbstractMethodError` or other linkage exceptions, - try doing `ant clean build`. Due to the way how Scala compiles traits, if a trait changes, then it's sometimes not enough to recompile - just that trait, but it might also be necessary to recompile its users. The `ant` tool is not smart enough to do that, which might lead to - very strange errors. Full-rebuilds fix the problem. Fortunately that's rarely necessary, because full-rebuilds take a lot of time-- the same 8-30 minutes as mentioned above. + try doing `sbt clean`. Due to the way Scala compiles traits, if a trait changes, then it's sometimes not enough to recompile + just that trait; it might also be necessary to recompile its users. The `sbt` tool is not smart enough to do that, which might lead to + very strange errors. Full rebuilds fix the problem. Fortunately that's rarely necessary, because full rebuilds take a lot of time -- the same 8-30 minutes as mentioned above. * Even on solid state drives packaging Scala distribution (i.e. creating jars from class files) is a non-trivial task. To save time here, - some people in our team do `ant quick.comp` instead of `ant` and then create custom scripts ([here](https://github.com/adriaanm/binfu/blob/master/scafu.sh) are some examples to get you started) to launch Scala from `build/quick/classes`. + some people in our team do `sbt compile` instead of `sbt dist/mkPack` and then create custom scripts using `sbt/mkBin` to launch Scala from `./build/quick/bin`. Also see [the Scala README](https://github.com/scala/scala#incremental-compilation) for tips on speeding up compile times. * Don't underestimate the power of `print`. When starting with Scala, I spent a lot of time in the debugger trying to figure out how things work. However later I found out that print-based debugging is often more effective than jumping around. While it might be obvious - to some, I'd like to explicitly mention that it's also useful to print stack traces to understand the flow of execution. When working with `Trees`, you might want to use `showRaw` to get the `AST` representation. -* You can publish your newly-built scala version locally to use it from sbt. Here's how: + to some, I'd like to explicitly mention that it's also useful to print stack traces to understand the flow of execution. When working with `Trees`, you might want to use the Scala `showRaw` to get the `AST` representation. +* You can publish your newly-built scala version locally using `sbt publishLocal` to use it from `sbt`. Here's how: - $ ant publish-local-opt -Dmaven.version.suffix="-test" + $ sbt publishLocal // This may take a while + ... $ sbt - [info] Set current project to test (in build file:/Users/georgii/workspace/test/) - > set resolvers += Resolver.mavenLocal - [info] Defining *:resolvers - [info] The new value will be used by *:externalResolvers - [info] Reapplying settings... - [info] Set current project to test (in build file:/Users/georgii/workspace/test/) - > ++2.12.0-test - [info] Setting version to 2.12.0-test - [info] Set current project to test (in build file:/Users/georgii/workspace/test/) + ... > console [info] Starting scala interpreter... - [info] - Welcome to Scala version 2.12.0-20140623-155543-8bdacad317 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51). + [info] + Welcome to Scala version 2.10.6 (OpenJDK 64-Bit Server VM, Java 1.8.0_91). Type in expressions to have them evaluated. Type :help for more information. @@ -212,7 +183,7 @@ Here are also some tips & tricks that have proven useful in Scala development: ### Documentation -There are several areas that one could contribute to-- there is the Scala library, the Scala compiler, and other tools such as Scaladoc. Each area has varying amounts of documentation. +There are several areas that one could contribute to -- there is the Scala library, the Scala compiler, and other tools such as Scaladoc. Each area has varying amounts of documentation. ##### The Scala Library @@ -263,22 +234,12 @@ but not tokens like `%n`. Looks like an easy fix. start = idx + 1 } -After applying the fix and running `ant`, our simple test case in `sandbox/Test.scala` started working! +After applying the fix and running `sbt compile`, our simple test case in `sandbox/Test.scala` started working! 18:51 ~/Projects/scala/sandbox (ticket/6725)$ cd .. - 18:51 ~/Projects/scala (ticket/6725)$ ant - Buildfile: /Users/xeno_by/Projects/scala/build.xml - + 18:51 ~/Projects/scala (ticket/6725)$ sbt compile ... - - quick.comp: - [scalacfork] Compiling 1 file to /Users/xeno_by/Projects/scala/build/quick/classes/compiler - [propertyfile] Updating property file: /Users/xeno_by/Projects/scala/build/quick/classes/compiler/compiler.properties - [stopwatch] [quick.comp.timer: 6.588 sec] - - ... - - BUILD SUCCESSFUL + [success] Total time: 18 s, completed Jun 6, 2016 9:03:02 PM Total time: 18 seconds 18:51 ~/Projects/scala (ticket/6725)$ cd sandbox @@ -332,15 +293,7 @@ Here are some more testing tips: [mima] } [mima] - BUILD FAILED - /localhome/jenkins/c/workspace/pr-scala-test/scala/build.xml:1530: The following error occurred while executing this line: - /localhome/jenkins/c/workspace/pr-scala-test/scala/build-ant-macros.xml:791: The following error occurred while executing this line: - /localhome/jenkins/c/workspace/pr-scala-test/scala/build-ant-macros.xml:773: Java returned: 2 - - Total time: 6 minutes 46 seconds - Build step 'Execute shell' marked build as failure - Archiving artifacts - Notifying upstream projects of job completion + ... Finished: FAILURE This means your change is backward or forward binary incompatible with the specified version (the check is performed by the [migration manager](https://github.com/typesafehub/migration-manager)). The error message is actually saying what you need to add to `bincompat-backward.whitelist.conf` or `bincompat-forward.whitelist.conf` to make the error go away. If you are getting this on an internal/experimental api, it should be safe to add suggested sections to the config. Otherwise, you might want to target a newer version of scala for this change. @@ -349,7 +302,7 @@ This means your change is backward or forward binary incompatible with the speci Now to make sure that my fix doesn't break anything I need to run the test suite using the `partest` tool we wrote to test Scala. Read up [the partest guide](partest-guide.html) to learn the details about partest, but in a nutshell you can either -run `ant test` to go through the entire test suite (30+ minutes) or use wildcards to limit the tests to something manageable: +run `sbt test` to go through the entire test suite (30+ minutes) or use wildcards to limit the tests to something manageable: 18:52 ~/Projects/scala/sandbox (ticket/6725)$ cd ../test 18:56 ~/Projects/scala/test (ticket/6725)$ partest files/run/*interpol* From 5532eb46c8ccd199485ee7dff88d97ec06f9e30d Mon Sep 17 00:00:00 2001 From: Chase Long Date: Tue, 7 Jun 2016 21:37:25 -0500 Subject: [PATCH 0096/3075] Changes per PR feedback --- contribute/hacker-guide.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index dab991eba5..09eb50a8a3 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -106,10 +106,10 @@ You need the following tools: * `sbt`, an interactive build tool commonly used in Scala projects. Acquiring sbt manually is not necessary -- the recommended approach is to download the [sbt-extras runner script](https://github.com/paulp/sbt-extras/blob/master/sbt) and use it in place of `sbt`. The script will download and run the correct version of sbt when run from the Scala repository's root directory. * `curl` -- the build uses `curl` in the `pull-binary-libs.sh` script to download bootstrap libs. -The majority of our team works on Linux and OS X, so these operating systems are guaranteed to work. Windows is supported, but it might have issues. Please report to [the issue tracker](https://issues.scala-lang.org/) if you encounter any. +OS X and Linux builds should work. Windows is supported, but it might have issues. Please report to [the issue tracker](https://issues.scala-lang.org/) if you encounter any. Building Scala is as easy as running `sbt dist/mkPack` in the root of your cloned repository. Be prepared to wait for a while -- a full "clean" build -takes 8+ minutes depending on your machine (and up to 30 minutes on older machines with less memory). Incremental builds are usually within 30-120 seconds range (again, your mileage might vary +takes 5+ minutes depending on your machine (longer on older machines with less memory). Incremental builds are usually within 20-120 seconds range (again, your mileage might vary with your hardware). ### IDE @@ -155,12 +155,8 @@ Now, implement your bugfix or new feature! Here are also some tips & tricks that have proven useful in Scala development: -* If after introducing changes or updating your clone, you get `AbstractMethodError` or other linkage exceptions, - try doing `sbt clean`. Due to the way Scala compiles traits, if a trait changes, then it's sometimes not enough to recompile - just that trait; it might also be necessary to recompile its users. The `sbt` tool is not smart enough to do that, which might lead to - very strange errors. Full rebuilds fix the problem. Fortunately that's rarely necessary, because full rebuilds take a lot of time -- the same 8-30 minutes as mentioned above. -* Even on solid state drives packaging Scala distribution (i.e. creating jars from class files) is a non-trivial task. To save time here, - some people in our team do `sbt compile` instead of `sbt dist/mkPack` and then create custom scripts using `sbt/mkBin` to launch Scala from `./build/quick/bin`. Also see [the Scala README](https://github.com/scala/scala#incremental-compilation) for tips on speeding up compile times. +* Even on solid state drives packaging Scala distribution (i.e. creating jars from class files) is a non-trivial task. To save time here, some people in our team do `sbt compile` instead of `sbt dist/mkPack` and then create custom scripts using `sbt/mkBin` to launch Scala from `./build/quick/bin/`. Also see [the Scala README](https://github.com/scala/scala#incremental-compilation) for tips on speeding up compile times. +* If after introducing changes or updating your clone, you get `AbstractMethodError` or other linkage exceptions, try doing `sbt clean` and building again. * Don't underestimate the power of `print`. When starting with Scala, I spent a lot of time in the debugger trying to figure out how things work. However later I found out that print-based debugging is often more effective than jumping around. While it might be obvious to some, I'd like to explicitly mention that it's also useful to print stack traces to understand the flow of execution. When working with `Trees`, you might want to use the Scala `showRaw` to get the `AST` representation. @@ -300,9 +296,9 @@ This means your change is backward or forward binary incompatible with the speci ### Verify -Now to make sure that my fix doesn't break anything I need to run the test suite using the `partest` tool we wrote to test Scala. -Read up [the partest guide](partest-guide.html) to learn the details about partest, but in a nutshell you can either -run `sbt test` to go through the entire test suite (30+ minutes) or use wildcards to limit the tests to something manageable: +Now to make sure that my fix doesn't break anything I need to run the test suite. The Scala test suite uses [JUnit](http://junit.org/junit4/) and [partest](partest-guide.html), a tool we wrote for testing Scala. +Run `sbt test` and `sbt partest` to run all of the JUnit and partest tests, respectively. +`partest` (not `sbt partest`) also allows you to run a subset of the tests using wildcards: 18:52 ~/Projects/scala/sandbox (ticket/6725)$ cd ../test 18:56 ~/Projects/scala/test (ticket/6725)$ partest files/run/*interpol* From 1ea529f4b4c2372c17561398ca1927a004daf7d7 Mon Sep 17 00:00:00 2001 From: Chase Long Date: Mon, 13 Jun 2016 20:11:59 -0500 Subject: [PATCH 0097/3075] Correct misleading instructions for publishing a local Scala version --- contribute/hacker-guide.md | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 09eb50a8a3..3426f37f82 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -160,20 +160,26 @@ Here are also some tips & tricks that have proven useful in Scala development: * Don't underestimate the power of `print`. When starting with Scala, I spent a lot of time in the debugger trying to figure out how things work. However later I found out that print-based debugging is often more effective than jumping around. While it might be obvious to some, I'd like to explicitly mention that it's also useful to print stack traces to understand the flow of execution. When working with `Trees`, you might want to use the Scala `showRaw` to get the `AST` representation. -* You can publish your newly-built scala version locally using `sbt publishLocal` to use it from `sbt`. Here's how: +* You can publish your newly-built scala version locally using `sbt publishLocal`. Then, you can invoke a REPL using your version: $ sbt publishLocal // This may take a while ... $ sbt ... - > console - [info] Starting scala interpreter... - [info] - Welcome to Scala version 2.10.6 (OpenJDK 64-Bit Server VM, Java 1.8.0_91). - Type in expressions to have them evaluated. - Type :help for more information. - - scala> + > scala + [info] Running scala.tools.nsc.MainGenericRunner -usejavacp + Welcome to Scala 2.12.0-20160613-195040-cd85531 (OpenJDK 64-Bit Server VM, Java 1.8.0_91). + Type in expressions for evaluation. Or try :help. + + scala> + +Alternatively, you can invoke a REPL using the bash script in `./build/quick/bin/`: + + $ ./build/quick/bin/scala + Welcome to Scala 2.12.0-20160613-195040-cd85531 (OpenJDK 64-Bit Server VM, Java 1.8.0_91). + Type in expressions for evaluation. Or try :help. + + scala> * Adding a macro to the `Predef` object is a pretty involved task. Due to bootstrapping, you cannot just throw a macro into it. For this reason, the process is more involved. You might want to follow the way `StringContext.f` itself is added. In short, you need to define your macro under `src/compiler/scala/tools/reflect/` and provide no implementation in `Predef` (`def fn = macro ???`). Now you have to set up the wiring. Add the name of your macro to `src/reflect/scala/reflect/internal/StdNames.scala`, add the needed links to it to `src/reflect/scala/reflect/internal/Definitions.scala`, and finally specify the bindings in `src/compiler/scala/tools/reflect/FastTrack.scala`. [Here's](https://github.com/folone/scala/commit/59536ea833ca16c985339727baed5d70e577b0fe) an example of adding a macro. From 2a94e25b660c8eed80c3e412933d61a2a7eb1835 Mon Sep 17 00:00:00 2001 From: Alex Xandra Albert Sim Date: Wed, 14 Sep 2016 16:27:15 +0700 Subject: [PATCH 0098/3075] Update Ensime's contributing and readme page The current "readme" and "contributing" links on Ensime gives us a standard Github 404 page. This commit updates the links to valid URLs. --- contribute/tools.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contribute/tools.md b/contribute/tools.md index 1757ae1005..494d2e54cf 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -76,8 +76,8 @@ Stuff changes. Found a broken link or something that needs updating on this page

Scala Support for Text Editors

Home | Issues | -ReadMe | -Contributing

+ReadMe | +Contributing

@@ -126,4 +126,4 @@ The following projects are important to the Scala community but are particularly - \ No newline at end of file + From a41edfc053abb0e97d951e9fdd462ebec99135e8 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Wed, 26 Oct 2016 10:54:45 -0700 Subject: [PATCH 0099/3075] Implement some review feedback, some polish of my own Reworks #438 --- contribute/hacker-guide.md | 54 ++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 3426f37f82..09532edecd 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -108,9 +108,9 @@ You need the following tools: OS X and Linux builds should work. Windows is supported, but it might have issues. Please report to [the issue tracker](https://issues.scala-lang.org/) if you encounter any. -Building Scala is as easy as running `sbt dist/mkPack` in the root of your cloned repository. Be prepared to wait for a while -- a full "clean" build -takes 5+ minutes depending on your machine (longer on older machines with less memory). Incremental builds are usually within 20-120 seconds range (again, your mileage might vary -with your hardware). +Building Scala is as easy as running `sbt dist/mkPack` in the root of your cloned repository. In general, it's much more efficient to enter the `sbt` shell once and run the various tasks from there, instead of running each task by launching `sbt some-task` on your command prompt. + +Be prepared to wait for a while -- a full "clean" build takes 5+ minutes depending on your machine (longer on older machines with less memory). On a recent laptop, incremental builds usually complete within 10-30 seconds. ### IDE @@ -155,31 +155,33 @@ Now, implement your bugfix or new feature! Here are also some tips & tricks that have proven useful in Scala development: -* Even on solid state drives packaging Scala distribution (i.e. creating jars from class files) is a non-trivial task. To save time here, some people in our team do `sbt compile` instead of `sbt dist/mkPack` and then create custom scripts using `sbt/mkBin` to launch Scala from `./build/quick/bin/`. Also see [the Scala README](https://github.com/scala/scala#incremental-compilation) for tips on speeding up compile times. -* If after introducing changes or updating your clone, you get `AbstractMethodError` or other linkage exceptions, try doing `sbt clean` and building again. +* After building your working copy with the `compile` sbt task, there's no need to leave the comfort of your sbt shell to try it out: the REPL is available as the `scala` task, and you can also run the compiler using the `scalac` task. If you prefer to run the REPL outside sbt, you can generate the scripts in `build/quick/bin` using the `dist/mkQuick` task. +* The sbt workflow is also great for debugging, as you can simply create a remote debugging session in your favorite IDE, and then activate the JVM options for the next time you run the `scala` or `scalac` tasks using: + +``` +> set javaOptions in compiler := List("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8002") +> scalac test.scala +[info] Running scala.tools.nsc.Main -usejavacp test.scala +Listening for transport dt_socket at address: 8002 +``` + +* Also see [the Scala README](https://github.com/scala/scala#incremental-compilation) for tips on speeding up compile times. +* If after introducing changes or updating your clone, you get `AbstractMethodError` or other linkage exceptions, try the `clean` task and building again. * Don't underestimate the power of `print`. When starting with Scala, I spent a lot of time in the debugger trying to figure out how things work. However later I found out that print-based debugging is often more effective than jumping around. While it might be obvious - to some, I'd like to explicitly mention that it's also useful to print stack traces to understand the flow of execution. When working with `Trees`, you might want to use the Scala `showRaw` to get the `AST` representation. -* You can publish your newly-built scala version locally using `sbt publishLocal`. Then, you can invoke a REPL using your version: - - $ sbt publishLocal // This may take a while - ... - $ sbt - ... - > scala - [info] Running scala.tools.nsc.MainGenericRunner -usejavacp - Welcome to Scala 2.12.0-20160613-195040-cd85531 (OpenJDK 64-Bit Server VM, Java 1.8.0_91). - Type in expressions for evaluation. Or try :help. - - scala> - -Alternatively, you can invoke a REPL using the bash script in `./build/quick/bin/`: - - $ ./build/quick/bin/scala - Welcome to Scala 2.12.0-20160613-195040-cd85531 (OpenJDK 64-Bit Server VM, Java 1.8.0_91). - Type in expressions for evaluation. Or try :help. - - scala> + to some, I'd like to explicitly mention that it's also useful to print stack traces to understand the flow of execution. When working with `Trees`, you might want to use `showRaw` to get the `AST` representation. +* You can publish your newly-built scala version locally using the `publishLocal` task in sbt. +* It's convenient to enable the following local settings to speed up your workflow (put these in `local.sbt` in your working copy): +``` +// skip docs for local publishing +publishArtifact in (Compile, packageDoc) in ThisBuild := false +// set version based on current sha, so that you can easily consume this build from another sbt project +baseVersionSuffix := s"local-${Process("tools/get-scala-commit-sha").lines.head.substring(0, 7)}" +// show more logging during a partest run +testOptions in IntegrationTest in LocalProject("test") ++= Seq(Tests.Argument("--show-log"), Tests.Argument("--show-diff")) +// if incremental compilation is compiling too much (should be fine under sbt 0.13.13) +// antStyle := true +``` * Adding a macro to the `Predef` object is a pretty involved task. Due to bootstrapping, you cannot just throw a macro into it. For this reason, the process is more involved. You might want to follow the way `StringContext.f` itself is added. In short, you need to define your macro under `src/compiler/scala/tools/reflect/` and provide no implementation in `Predef` (`def fn = macro ???`). Now you have to set up the wiring. Add the name of your macro to `src/reflect/scala/reflect/internal/StdNames.scala`, add the needed links to it to `src/reflect/scala/reflect/internal/Definitions.scala`, and finally specify the bindings in `src/compiler/scala/tools/reflect/FastTrack.scala`. [Here's](https://github.com/folone/scala/commit/59536ea833ca16c985339727baed5d70e577b0fe) an example of adding a macro. From 6a5ddf970a857b71779f8e023147ac299f2b0d8d Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Tue, 8 Nov 2016 14:11:21 -0800 Subject: [PATCH 0100/3075] fix Github -> GitHub --- contribute/codereviews.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/codereviews.md b/contribute/codereviews.md index 1b9a881b0c..a2df66bd10 100644 --- a/contribute/codereviews.md +++ b/contribute/codereviews.md @@ -43,7 +43,7 @@ own pull requests.

The Scala language web site.

-

All Scala Github Projects

+

All Scala GitHub Projects

For other PRs, follow the scala project from here.

From 78590ba20a3272880bd47994e5a31c7cbae24f01 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Tue, 15 Nov 2016 15:27:38 -0800 Subject: [PATCH 0101/3075] recommend sbt, not Activator and remove all mention of Activator from the site (well, except from some old release announcements) --- contribute/documentation.md | 8 -------- contribute/index.md | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/contribute/documentation.md b/contribute/documentation.md index 6b5c81a0fc..b499571154 100644 --- a/contribute/documentation.md +++ b/contribute/documentation.md @@ -7,7 +7,6 @@ title: Documentation Contributions There are several ways you can help out with the improvement of Scala documentation. These include: * API Documentation in Scaladoc -* Code examples and tutorials in activator templates. * Guides, Overviews, Tutorials, Cheat Sheets and more on the docs.scala-lang.org site * Updating scala-lang.org @@ -28,13 +27,6 @@ Please *follow the issue submission process closely* to help prevent duplicate i [submit new Scaladoc](./scala-standard-library-api-documentation.html) without creating an issue, but please look to see if there is an issue already submitted for your task and claim it if there is. If not, please post your intention to work on a specific scaladoc task on scala-internals so that people know what you are doing. -### Examples/Tutorials in Activator Templates - -[Lightbend Activator](https://www.lightbend.com/community/core-tools/activator-and-sbt) -is a tool based on SBT, with a UI mode that is ideal for code based tutorials, overviews and walk-throughs. To contribute an example in activator, you can fork an existing template, edit it, add a tutorial, upload it to github and then submit the github project into the template repository. It's the fastest way to produce a working code example with tutorial. - -Please see [Contributing an Activator Template](https://www.lightbend.com/activator/template/contribute) for more details. - ### The Main Scala Documentation Site [docs.scala-lang.org](https://wiki.scala-lang.org/) houses the primary source of written, non-API documentation for Scala. It's a github project that you can fork and submit pull requests from. It includes: diff --git a/contribute/index.md b/contribute/index.md index 925e83248e..0a1e2fbaef 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -27,7 +27,7 @@ Coordination of contribution efforts takes place on the
From 891183e26da4c3f9ccbea5b5bb888aa40e682469 Mon Sep 17 00:00:00 2001 From: Jarrod Brockman Date: Wed, 16 Nov 2016 14:05:22 +0100 Subject: [PATCH 0102/3075] fix a lot of broken links --- contribute/codereviews.md | 2 +- contribute/documentation.md | 3 +-- contribute/guide.md | 9 ++++----- contribute/hacker-guide.md | 2 +- contribute/index.md | 2 +- contribute/scala-standard-library-api-documentation.md | 2 +- 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/contribute/codereviews.md b/contribute/codereviews.md index a2df66bd10..d0d9a111c3 100644 --- a/contribute/codereviews.md +++ b/contribute/codereviews.md @@ -5,7 +5,7 @@ title: Code Review Contributions ## Code Review Contributions In addition to [bug fixing](./guide.html), you can help us review -[waiting pull requests](#pull_requests_awaiting_comment). +[waiting pull requests](#pull-requests-awaiting-comment). This is also a good (and recommended) way to get to know the feel of the bug-fixing and submissions process before jumping in with your own pull requests. diff --git a/contribute/documentation.md b/contribute/documentation.md index 6b5c81a0fc..27aab024d2 100644 --- a/contribute/documentation.md +++ b/contribute/documentation.md @@ -21,7 +21,7 @@ Thanks The Scala API documentation lives with the scala project source code. There are many ways you can help with improving Scaladoc, including: -* [Log issues for missing scaladoc documentation](./scala-standard-library-api-documentation.html#contribute_api_documentation_bug_reports) - +* [Log issues for missing scaladoc documentation](./scala-standard-library-api-documentation.html#contribute-api-documentation-bug-reports) - Please *follow the issue submission process closely* to help prevent duplicate issues being created. * [Claim Scaladoc Issues and Provide Documentation](./scala-standard-library-api-documentation.html) - please claim issues prior to working on a specific scaladoc task to prevent duplication of effort. If you sit on an issue for too long without submitting a pull request, it will revert back to unassigned and you will need to re-claim it. * You can also just @@ -61,4 +61,3 @@ to Scala and related projects) is provided on the main Please read both the [docs.scala-lang.org contribution](http://docs.scala-lang.org/contribute.html) document and the [scala-lang.org github README](https://github.com/scala/scala-lang#scala-langorg) before embarking on any changes to the Scala language site, as it uses the same Jekyll markdown tool and many of the same conventions as the Scala documentation site. - diff --git a/contribute/guide.md b/contribute/guide.md index b92bd2fe89..02b560b7fc 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -17,7 +17,7 @@ title: Contributing guide
-

Community issues

+

Community issues

Get cracking on some easy to approach issues.

@@ -52,9 +52,9 @@ unencumbered by copyrights or patents. This is the impatient developer's checklist for the steps to submit a bug-fix pull request to the Scala project. For more information, description and justification for the steps, follow the links in that step. Further specific instructions for the release of Scala you are targeting can be found in the `CONTRIBUTING.md` file for that [github branch](https://github.com/scala/scala) -1. [Select a bug to fix from JIRA](/contribute/index.html#community_tickets), or if you found the bug yourself and want to fix it, [create a JIRA issue](./bug-reporting-guide.html) (but please -[make sure it's not a duplicate](./bug-reporting-guide.html#reporting_confirmed_bugs_is_a_sin)). -2. Optional ([but recommended](./scala-internals.html#why_its_a_good_idea)), announce your intention to work on the bug on [scala-internals](./scala-internals.html). After all, don't you want to work on a team with +1. [Select a bug to fix from JIRA](/contribute/index.html#community-tickets), or if you found the bug yourself and want to fix it, [create a JIRA issue](./bug-reporting-guide.html) (but please +[make sure it's not a duplicate](./bug-reporting-guide.html#reporting-confirmed-bugs-is-a-sin)). +2. Optional ([but recommended](./scala-internals.html#why-its-a-good-idea)), announce your intention to work on the bug on [scala-internals](./scala-internals.html). After all, don't you want to work on a team with [these friendly people](./hacker-guide.html#connect) - it's one of the perks of contributing. 3. [Fork the Scala repository](./hacker-guide.html#fork) and clone your fork (if you haven't already). 4. [Create a feature branch](./hacker-guide.html#branch) to work on: use the branch name `issue/NNNN` where NNNN is the JIRA issue number. @@ -77,4 +77,3 @@ on the [scala-internals](http://groups.google.com/group/scala-internals) mailing Contributions, big or small, simple or complex, controversial or undisputed, need to materialize as patches against the Scala project source tree. The [hacker guide](hacker-guide.html) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. - diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 09532edecd..897c97b1a2 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -28,7 +28,7 @@ Sometimes it's appealing to hack alone and not to have to interact with others o this might not be the very best idea. There are people in the Scala community who have spent years accumulating knowledge about Scala libraries and internals. They might provide unique insights and, what's even better, direct assistance in their areas, so it is not only advantageous, but recommended to communicate with the community about your new patch. -Typically bug fixes and new features start out as an idea or an experiment posted on one of [our mailing lists]({{ site.baseurl }}/community/index.html#mailing_lists) to find out how people feel +Typically bug fixes and new features start out as an idea or an experiment posted on one of [our mailing lists]({{ site.baseurl }}/community/index.html#mailing-lists) to find out how people feel about things you want to implement. People proficient in certain areas of Scala usually monitor mailing lists, so you'll often get some help by simply posting a message. But the most efficient way to connect is to cc your message to one of the people responsible for maintaining the aspect of Scala which you wish to contribute to. diff --git a/contribute/index.md b/contribute/index.md index 925e83248e..2fdf75fc71 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -56,7 +56,7 @@ Coordination of contribution efforts takes place on the

Enhance the Scala tools with features for build tools, IDE plug-ins and other related projects.

-

Compiler/Language

+

Compiler/Language

Larger language features and compiler enhancements including language specification and SIPs.

diff --git a/contribute/scala-standard-library-api-documentation.md b/contribute/scala-standard-library-api-documentation.md index bc57a163df..37e84bd76e 100644 --- a/contribute/scala-standard-library-api-documentation.md +++ b/contribute/scala-standard-library-api-documentation.md @@ -75,7 +75,7 @@ component so that they show up in the correct issue filters. Please familiarize yourself with the following before contributing new API documentation to save time, effort, mistakes and repetition. -* [Forking the Repo](./hacker-guide.html#2_set_up) - follow the setup steps through +* [Forking the Repo](./hacker-guide.html#set-up) - follow the setup steps through the Branch section. If providing new documentation related to an existing JIRA issue, use `issue/NNNN` or `ticket/NNNN` as the guide states. If providing API documentation with no associated JIRA issue, use `scaladoc/xxxx` instead. From ffe3a69da6552a2a9a56da52b92d97665fb46863 Mon Sep 17 00:00:00 2001 From: Jarrod Brockman Date: Thu, 17 Nov 2016 08:52:08 +0100 Subject: [PATCH 0103/3075] fix blank alt tags --- contribute/tools.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/contribute/tools.md b/contribute/tools.md index 494d2e54cf..877297636c 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -24,7 +24,7 @@ Stuff changes. Found a broken link or something that needs updating on this page
- +sbt logo

sbt

Interactive build tool.

Home | @@ -33,7 +33,7 @@ Stuff changes. Found a broken link or something that needs updating on this page Contributing

- +scala logo

Scaladoc Tool

(Contribute through scala/scala)

Home | @@ -45,7 +45,7 @@ Stuff changes. Found a broken link or something that needs updating on this page

-

Scala IDE

+scala IDE logo

Scala IDE

The Eclipse Scala IDE project.

Home | Issues | @@ -53,7 +53,7 @@ Stuff changes. Found a broken link or something that needs updating on this page Contributing

-

DBuild

+dbuild logo

DBuild

Multi-project build tool.

Home | Issues | @@ -64,7 +64,7 @@ Stuff changes. Found a broken link or something that needs updating on this page

- +scala logo

Partest

Scala Compiler/Library Testing

Home | @@ -72,7 +72,7 @@ Stuff changes. Found a broken link or something that needs updating on this page ReadMe

-

Ensime

+ensime logo

Ensime

Scala Support for Text Editors

Home | Issues | @@ -83,7 +83,7 @@ Stuff changes. Found a broken link or something that needs updating on this page

-

Scoverage

+scoverage logo

Scoverage

Scala code coverage tool

Home | Issues | @@ -91,7 +91,7 @@ Stuff changes. Found a broken link or something that needs updating on this page Contributing

- +scala logo

Abide

Lint tooling for Scala

Home | @@ -109,7 +109,7 @@ The following projects are important to the Scala community but are particularly

- +scala logo

Scalap

Scala Decoder (part of scala/scala)

Issues | @@ -117,7 +117,7 @@ The following projects are important to the Scala community but are particularly Contributing

-

Scalariform

+white line

Scalariform

Scala code formatter

Home | Issues | From c46edc10b100bb44c25a54356e12b708b6975153 Mon Sep 17 00:00:00 2001 From: "Aaron S. Hawley" Date: Sat, 19 Nov 2016 09:55:19 -0500 Subject: [PATCH 0104/3075] Fix formatting problems in hacker guide --- contribute/hacker-guide.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 897c97b1a2..db4e06e037 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -133,7 +133,7 @@ When hacking on your topic of choice, you'll be modifying Scala, compiling it an Typically you would want to first make sure that your changes work on a small example and afterwards verify that nothing break by running a comprehensive test suite. -We'll start by creating a `sandbox` directory (`./sandbox is listed in the .gitignore of the Scala repository), which will hold a single test file and its compilation results. First, let's make sure that +We'll start by creating a `sandbox` directory (`./sandbox` is listed in the .gitignore of the Scala repository), which will hold a single test file and its compilation results. First, let's make sure that [the bug](https://issues.scala-lang.org/browse/SI-6725) is indeed reproducible by putting together a simple test and compiling and running it with the Scala compiler that we built using `sbt`. The Scala compiler that we just built is located in `build/pack/bin`. 17:25 ~/Projects/scala (ticket/6725)$ mkdir sandbox @@ -172,6 +172,7 @@ Listening for transport dt_socket at address: 8002 to some, I'd like to explicitly mention that it's also useful to print stack traces to understand the flow of execution. When working with `Trees`, you might want to use `showRaw` to get the `AST` representation. * You can publish your newly-built scala version locally using the `publishLocal` task in sbt. * It's convenient to enable the following local settings to speed up your workflow (put these in `local.sbt` in your working copy): + ``` // skip docs for local publishing publishArtifact in (Compile, packageDoc) in ThisBuild := false From c27f49c1cd951c31f7d3f2bf9b07f5d362acb967 Mon Sep 17 00:00:00 2001 From: Jarrod Brockman Date: Sun, 20 Nov 2016 09:47:02 +0100 Subject: [PATCH 0105/3075] fix miscellaneous links --- contribute/tools.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contribute/tools.md b/contribute/tools.md index 877297636c..008a1425a1 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -12,12 +12,12 @@ Typically, issues for these projects will be reported and kept in the github pro Many of these projects have a gitter channel (usually listed in the README or CONTRIBUTING documents) which is a great place to discuss proposed work before commencing. There are some projects in this section that are in -[particular need](#projects_in_particular_need) so please check those out +[particular need](#projects-in-particular-need) so please check those out if you would like to help revive them. ### Broken Links? -Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](./documentation.html#updating_scalalangorg) to fix it. +Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](./documentation.html#updating-scala-langorg) to fix it. ### Projects From f2b3a20ec9486c615eed8146248a9c23e450adef Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Wed, 7 Dec 2016 12:47:28 -0800 Subject: [PATCH 0106/3075] 2.11 -> 2.12 in some more places --- contribute/hacker-guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index db4e06e037..8d7903fbea 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -8,7 +8,7 @@ This guide is intended to help you get from an idea of fixing a bug or implement This guide covers the entire process, from the conception of your idea or bugfix to the point where it is merged into Scala. Throughout, we will use a running example of an idea or bugfix one might wish to contribute. -Other good starting points for first-time contributors include the [Scala README](https://github.com/scala/scala#get-in-touch) and [contributor's guidelines](https://github.com/scala/scala/blob/2.11.x/CONTRIBUTING.md). +Other good starting points for first-time contributors include the [Scala README](https://github.com/scala/scala#get-in-touch) and [contributor's guidelines](https://github.com/scala/scala/blob/2.12.x/CONTRIBUTING.md). ## The Running Example @@ -336,7 +336,7 @@ Let's go into each of these points in more detail. The [Git Basics](http://git-scm.com/book/en/Git-Basics) chapter in the Git online book covers most of the basic workflow during this stage. There are two things you should know here: -1. Commit messages are often the only way to understand the intentions of authors of code written a few years ago. Thus, writing a quality is of utmost importance. The more context you provide for the change you've introduced, the larger the chance that some future maintainer understand your intentions. Consult [the pull request policies](https://github.com/scala/scala/blob/2.11.x/CONTRIBUTING.md) for more information about the desired style of your commits. +1. Commit messages are often the only way to understand the intentions of authors of code written a few years ago. Thus, writing a quality is of utmost importance. The more context you provide for the change you've introduced, the larger the chance that some future maintainer understand your intentions. Consult [the pull request policies](https://github.com/scala/scala/blob/2.12.x/CONTRIBUTING.md) for more information about the desired style of your commits. 2. Keeping Scala's git history clean is also important. Therefore we won't accept pull requests for bug fixes that have more than one commit. For features, it is okay to have several commits, but all tests need to pass after every single commit. To clean up your commit structure, you want to [rewrite history](http://git-scm.com/book/en/Git-Branching-Rebasing) using `git rebase` so that your commits are against the latest revision of `master`. Once you are satisfied with your work, synced with `master` and cleaned up your commits you are ready to submit a patch to the central Scala repository. Before proceeding make sure you have pushed all of your local changes to your fork on GitHub. From 1a258055bd0966a517c50f8113516e53f2393ad9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20de=20Sil=C3=B3niz=20Sandino?= Date: Wed, 8 Feb 2017 13:11:11 +0100 Subject: [PATCH 0107/3075] First migration of content pages to new content layout - First migration to using pretty permalinks --- contribute/bug-reporting-guide.md | 4 ++- contribute/codereviews.md | 10 ++++--- contribute/corelibs.md | 10 ++++--- contribute/documentation.md | 10 ++++--- contribute/guide.md | 30 ++++++++++--------- contribute/hacker-guide.md | 4 ++- contribute/index.md | 22 +++++++------- contribute/partest-guide.md | 4 ++- contribute/scala-internals.md | 4 ++- ...cala-standard-library-api-documentation.md | 4 ++- contribute/tools.md | 12 ++++---- 11 files changed, 68 insertions(+), 46 deletions(-) diff --git a/contribute/bug-reporting-guide.md b/contribute/bug-reporting-guide.md index 960f40b704..f4c8282a78 100644 --- a/contribute/bug-reporting-guide.md +++ b/contribute/bug-reporting-guide.md @@ -1,6 +1,8 @@ --- -layout: page title: Bug Reporting +layout: inner-page-no-masthead +permalink: /contribute/bug-reporting-guide/ +includeTOC: true --- The Scala project tracker is located at [http://issues.scala-lang.org](http://issues.scala-lang.org). Before you submit a bug make sure that it is certainly a bug by following instructions in *Is it a Bug?*. diff --git a/contribute/codereviews.md b/contribute/codereviews.md index d0d9a111c3..9239fa8c14 100644 --- a/contribute/codereviews.md +++ b/contribute/codereviews.md @@ -1,10 +1,12 @@ --- -layout: page title: Code Review Contributions +layout: inner-page-no-masthead +permalink: /contribute/codereviews/ +includeTOC: true --- ## Code Review Contributions -In addition to [bug fixing](./guide.html), you can help us review +In addition to [bug fixing](/contribute/guide/), you can help us review [waiting pull requests](#pull-requests-awaiting-comment). This is also a good (and recommended) way to get to know the feel of the bug-fixing and submissions process before jumping in with your @@ -13,7 +15,7 @@ own pull requests. ### Review Guidelines -[Code of Conduct reminder](../conduct.html) +[Code of Conduct reminder](/conduct/) * Keep comments on-topic, concise and precise. * Attach comments to particular lines or regions they pertain to whenever possible. @@ -49,4 +51,4 @@ own pull requests.

-Also note that the [Tools contributions](./tools.html) page has more projects that will generate pull requests. +Also note that the [Tools contributions](/contribute/tools/) page has more projects that will generate pull requests. diff --git a/contribute/corelibs.md b/contribute/corelibs.md index 6e1abbb0d7..1f34d150b0 100644 --- a/contribute/corelibs.md +++ b/contribute/corelibs.md @@ -1,14 +1,16 @@ --- -layout: page title: Core Library Contributions +layout: inner-page-no-masthead +permalink: /contribute/corelibs/ +includeTOC: true --- ## Core Library Contributions There are several options for contributing to Scala's core libraries. You can: -* Help with [Documentation](./scala-standard-library-api-documentation.html). -* [Report Bugs or Issues](./bug-reporting-guide.html) against the core libraries. -* [Fix Bugs or Issues](./guide.html) against the +* Help with [Documentation](/contribute/scala-standard-library-api-documentation/). +* [Report Bugs or Issues](/contribute/bug-reporting-guide/) against the core libraries. +* [Fix Bugs or Issues](/contribute/guide/) against the [reported library bugs/issues](https://issues.scala-lang.org/issues/?filter=13001). * Contribute significant new functionality or a new API by submitting a Scala Library Improvement Process (SLIP) Document. diff --git a/contribute/documentation.md b/contribute/documentation.md index 7657cbf699..2746fa77dc 100644 --- a/contribute/documentation.md +++ b/contribute/documentation.md @@ -1,6 +1,8 @@ --- -layout: page title: Documentation Contributions +layout: inner-page-no-masthead +permalink: /contribute/documentation/ +includeTOC: true --- ## Contributing Documentation to the Scala project @@ -20,11 +22,11 @@ Thanks The Scala API documentation lives with the scala project source code. There are many ways you can help with improving Scaladoc, including: -* [Log issues for missing scaladoc documentation](./scala-standard-library-api-documentation.html#contribute-api-documentation-bug-reports) - +* [Log issues for missing scaladoc documentation](/contribute/scala-standard-library-api-documentation/#contribute-api-documentation-bug-reports) - Please *follow the issue submission process closely* to help prevent duplicate issues being created. -* [Claim Scaladoc Issues and Provide Documentation](./scala-standard-library-api-documentation.html) - please claim issues prior to working on a specific scaladoc task to prevent duplication of effort. If you sit on an issue for too long without submitting a pull request, it will revert back to unassigned and you will need to re-claim it. +* [Claim Scaladoc Issues and Provide Documentation](/contribute/scala-standard-library-api-documentation/) - please claim issues prior to working on a specific scaladoc task to prevent duplication of effort. If you sit on an issue for too long without submitting a pull request, it will revert back to unassigned and you will need to re-claim it. * You can also just -[submit new Scaladoc](./scala-standard-library-api-documentation.html) +[submit new Scaladoc](/contribute/scala-standard-library-api-documentation/) without creating an issue, but please look to see if there is an issue already submitted for your task and claim it if there is. If not, please post your intention to work on a specific scaladoc task on scala-internals so that people know what you are doing. ### The Main Scala Documentation Site diff --git a/contribute/guide.md b/contribute/guide.md index 02b560b7fc..afd3572c53 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -1,6 +1,8 @@ --- -layout: page title: Contributing guide +layout: inner-page-no-masthead +permalink: /contribute/guide/ +includeTOC: true ---
@@ -10,7 +12,7 @@ title: Contributing guide

Get a peek into the inners of the Scala compiler.

-

Report an issue

+

Report an issue

File a bug report or a feature request.

@@ -21,7 +23,7 @@ title: Contributing guide

Get cracking on some easy to approach issues.

-

Hacker's guide

+

Hacker's guide

Learn to write good code and improve your chances of contributing to the Scala galaxy.

@@ -52,19 +54,19 @@ unencumbered by copyrights or patents. This is the impatient developer's checklist for the steps to submit a bug-fix pull request to the Scala project. For more information, description and justification for the steps, follow the links in that step. Further specific instructions for the release of Scala you are targeting can be found in the `CONTRIBUTING.md` file for that [github branch](https://github.com/scala/scala) -1. [Select a bug to fix from JIRA](/contribute/index.html#community-tickets), or if you found the bug yourself and want to fix it, [create a JIRA issue](./bug-reporting-guide.html) (but please -[make sure it's not a duplicate](./bug-reporting-guide.html#reporting-confirmed-bugs-is-a-sin)). -2. Optional ([but recommended](./scala-internals.html#why-its-a-good-idea)), announce your intention to work on the bug on [scala-internals](./scala-internals.html). After all, don't you want to work on a team with -[these friendly people](./hacker-guide.html#connect) - it's one of the perks of contributing. -3. [Fork the Scala repository](./hacker-guide.html#fork) and clone your fork (if you haven't already). -4. [Create a feature branch](./hacker-guide.html#branch) to work on: use the branch name `issue/NNNN` where NNNN is the JIRA issue number. -5. [Fix the bug, or implement the new small feature](./hacker-guide.html#implement), include new tests (yes, for bug fixes too). -6. [Test, rinse](./hacker-guide.html#test) and [test some more](./partest-guide.html) until [all the tests pass](./hacker-guide.html#verify). -7. [Commit your changes](./hacker-guide.html#commit) to your feature branch in your fork. Please choose your commit message based on the [Git Hygiene](https://github.com/scala/scala#user-content-git-hygiene) section of the Scala project README. +1. [Select a bug to fix from JIRA](/contribute/#community-tickets), or if you found the bug yourself and want to fix it, [create a JIRA issue](/contribute/bug-reporting-guide/) (but please +[make sure it's not a duplicate](/contribute/bug-reporting-guide/#reporting-confirmed-bugs-is-a-sin)). +2. Optional ([but recommended](/contribute/scala-internals/#why-its-a-good-idea)), announce your intention to work on the bug on [scala-internals](/contribute/scala-internals/). After all, don't you want to work on a team with +[these friendly people](/contribute/hacker-guide/#connect) - it's one of the perks of contributing. +3. [Fork the Scala repository](/contribute/hacker-guide/#fork) and clone your fork (if you haven't already). +4. [Create a feature branch](/contribute/hacker-guide/#branch) to work on: use the branch name `issue/NNNN` where NNNN is the JIRA issue number. +5. [Fix the bug, or implement the new small feature](/contribute/hacker-guide/#implement), include new tests (yes, for bug fixes too). +6. [Test, rinse](/contribute/hacker-guide/#test) and [test some more](/contribute/partest-guide/) until [all the tests pass](/contribute/hacker-guide/#verify). +7. [Commit your changes](/contribute/hacker-guide#commit) to your feature branch in your fork. Please choose your commit message based on the [Git Hygiene](https://github.com/scala/scala#user-content-git-hygiene) section of the Scala project README. 8. If necessary [re-write git history](http://git-scm.com/book/en/Git-Branching-Rebasing) so that [commits are organized by major steps to the fix/feature]( https://github.com/scala/scala#git-hygiene). For bug fixes, a single commit is requested, for features several commits may be desirable (but each separate commit must compile and pass all tests) 9. [Submit a pull request](./hacker-guide.html#submit) following the [Scala project pull-request guidelines](http://docs.scala-lang.org/scala/pull-request-policy.html). -10. [Work with a reviewer](https://github.com/scala/scala#reviewing) to [get your pull request merged in](./hacker-guide.html#review). +10. [Work with a reviewer](https://github.com/scala/scala#reviewing) to [get your pull request merged in](/contribute/hacker-guide/#review). 11. Celebrate! Need more information or a little more hand-holding for the first one? We got you covered: take a read through the entire [Hacker Guide](./hacker-guide.html) for an example of implementing a new feature (some of the steps can be skipped for bug fixes, this will be obvious from reading it, but many of the steps here will help with bug fixes too). @@ -76,4 +78,4 @@ and on the implementation plan. Announce the change on the [scala-internals](http://groups.google.com/group/scala-internals) mailing list and get developer feedback. For really complex changes, a [Scala Improvement Process (SIP)](http://docs.scala-lang.org/sips/) document might be required, but the first step is always to discuss it on the mailing list and if a SIP is required, that will be discussed on the mailing list. Contributions, big or small, simple or complex, controversial or undisputed, need to materialize as patches against -the Scala project source tree. The [hacker guide](hacker-guide.html) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. +the Scala project source tree. The [hacker guide](/contribute/hacker-guide/) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 8d7903fbea..ebdad9652b 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -1,7 +1,9 @@ --- -layout: page title: Scala hacker guide by: Eugene Burmako +layout: inner-page-no-masthead +permalink: /contribute/hacker-guide/ +includeTOC: true ---
This guide is intended to help you get from an idea of fixing a bug or implementing a new feature into a nightly Scala build, and, ultimately, to a production release of Scala incorporating your idea. diff --git a/contribute/index.md b/contribute/index.md index 1a2f7c7c5b..dcc78e8149 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -1,6 +1,8 @@ --- -layout: page title: Contribute +layout: inner-page-no-masthead +permalink: /contribute/ +includeTOC: true --- The Scala programming language is an open source project with a very @@ -26,37 +28,37 @@ Coordination of contribution efforts takes place on the
-

Bug Fixes

-

Issues with the tools, core libraries and compiler. Also you can help us by reporting bugs

+

Bug Fixes

+

Issues with the tools, core libraries and compiler. Also you can help us by reporting bugs

-

Code Reviews

+

Code Reviews

Review pull requests against scala/scala, scala/scala-lang, scala/scala.github.com and others.

-

Core Libraries

+

Core Libraries

Update and expand the capabilities of the core (and associated) Scala libraries.

-

IDE and Build Tools

+

IDE and Build Tools

Enhance the Scala tools with features for build tools, IDE plug-ins and other related projects.

-

Compiler/Language

+

Compiler/Language

Larger language features and compiler enhancements including language specification and SIPs.

@@ -109,7 +111,7 @@ with their own maintainers and community of contributors. Helping out one of these projects is another way to help Scala. Consider lending on a hand on a project you're already using. Or, to find out about other projects, see the -[Libraries and Tools section](../community/index.html#community-libraries-and-tools) +[Libraries and Tools section](../community/#community-libraries-and-tools) on our Community page. ### Scala Community Build diff --git a/contribute/partest-guide.md b/contribute/partest-guide.md index e681c569fe..be37d6fc12 100644 --- a/contribute/partest-guide.md +++ b/contribute/partest-guide.md @@ -1,6 +1,8 @@ --- -layout: page title: Running the Test Suite +layout: inner-page-no-masthead +permalink: /contribute/partest-guide/ +includeTOC: true --- Partest is a custom parallel testing tool that we use to run the test suite for the Scala compiler and library. Go the scala project folder from your local checkout and run it via `ant` or standalone as follows. diff --git a/contribute/scala-internals.md b/contribute/scala-internals.md index 5bd97ed8a8..831f2cc864 100644 --- a/contribute/scala-internals.md +++ b/contribute/scala-internals.md @@ -1,6 +1,8 @@ --- -layout: page title: Scala Internals Mailing List +layout: inner-page-no-masthead +permalink: /contribute/scala-internals/ +includeTOC: true --- ## scala-internals diff --git a/contribute/scala-standard-library-api-documentation.md b/contribute/scala-standard-library-api-documentation.md index 37e84bd76e..68df995375 100644 --- a/contribute/scala-standard-library-api-documentation.md +++ b/contribute/scala-standard-library-api-documentation.md @@ -1,6 +1,8 @@ --- -layout: page title: Contribute to API Documentation +layout: inner-page-no-masthead +permalink: /contribute/scala-standard-library-api-documentation/ +includeTOC: true --- This page is specific to API documentation contributions – that is, API diff --git a/contribute/tools.md b/contribute/tools.md index 008a1425a1..876ce88c1c 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -1,12 +1,14 @@ --- -layout: page title: IDE and Build Tool Contributions +layout: inner-page-no-masthead +permalink: /contribute/tools/ +includeTOC: true --- ## Contributing to IDE and Build Tools The links below are to a number of Scala build and IDE related projects that are important in the larger Scala space, and which welcome contributions. -Since these tools are in separate projects, they may (and likely will) have their own rules and guidelines for contributing. The [Hacker Guide](./hacker-guide.html) and [Bug-fixing](guide.html) pages will likely have much in the way of related information on how to contribute to these projects, and are recommended reading. You should also check the README.md and (if it's present) CONTRIBUTING.md files from the actual projects before contributing to them. +Since these tools are in separate projects, they may (and likely will) have their own rules and guidelines for contributing. The [Hacker Guide](/contribute/hacker-guide/) and [Bug-fixing](/contribute/guide/) pages will likely have much in the way of related information on how to contribute to these projects, and are recommended reading. You should also check the README.md and (if it's present) CONTRIBUTING.md files from the actual projects before contributing to them. Typically, issues for these projects will be reported and kept in the github project issue tracker for that project rather than in the Scala project JIRA. Many of these projects have a gitter channel (usually listed in the README or CONTRIBUTING documents) which is a great place to discuss proposed work before commencing. @@ -17,7 +19,7 @@ if you would like to help revive them. ### Broken Links? -Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](./documentation.html#updating-scala-langorg) to fix it. +Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](/contribute/documentation/#updating-scala-langorg) to fix it. ### Projects @@ -39,7 +41,7 @@ Stuff changes. Found a broken link or something that needs updating on this page

Home | Issues | ReadMe | -Contributing

+Contributing

@@ -114,7 +116,7 @@ The following projects are important to the Scala community but are particularly

Scala Decoder (part of scala/scala)

Issues | ReadMe | -Contributing

+Contributing

white line

Scalariform

From b58955fa85531e7be82639d5d6acf44b779f0f17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20de=20Sil=C3=B3niz=20Sandino?= Date: Wed, 8 Feb 2017 17:25:34 +0100 Subject: [PATCH 0108/3075] Short items list for the contribute subpages --- _contribute_resources/1-documentation.md | 6 + _contribute_resources/2-bug-fixes.md | 6 + _contribute_resources/3-code-reviews.md | 8 + _contribute_resources/4-core-libraries.md | 6 + .../5-ide-and-build-tools.md | 6 + _contribute_resources/6-compiler-language.md | 6 + contribute/index.md | 74 +------ contribute/tools.md | 187 ++++++++---------- 8 files changed, 126 insertions(+), 173 deletions(-) create mode 100644 _contribute_resources/1-documentation.md create mode 100644 _contribute_resources/2-bug-fixes.md create mode 100644 _contribute_resources/3-code-reviews.md create mode 100644 _contribute_resources/4-core-libraries.md create mode 100644 _contribute_resources/5-ide-and-build-tools.md create mode 100644 _contribute_resources/6-compiler-language.md diff --git a/_contribute_resources/1-documentation.md b/_contribute_resources/1-documentation.md new file mode 100644 index 0000000000..27739dee6a --- /dev/null +++ b/_contribute_resources/1-documentation.md @@ -0,0 +1,6 @@ +--- +title: Documentation +link: /contribute/documentation/ +icon: fa fa-file-text +--- +[Scaladoc (API)](/contribute/scala-standard-library-api-documentation/),[docs.scala-lang.org](http://docs.scala-lang.org/contribute.html) and [scala-lang.org](https://github.com/scala/scala-lang). \ No newline at end of file diff --git a/_contribute_resources/2-bug-fixes.md b/_contribute_resources/2-bug-fixes.md new file mode 100644 index 0000000000..d10adb7908 --- /dev/null +++ b/_contribute_resources/2-bug-fixes.md @@ -0,0 +1,6 @@ +--- +title: Bug fixes +link: /contribute/guide/ +icon: fa fa-pencil +--- +Issues with the tools, core libraries and compiler. Also you can help us by [reporting bugs](/contribute/bug-reporting-guide/). \ No newline at end of file diff --git a/_contribute_resources/3-code-reviews.md b/_contribute_resources/3-code-reviews.md new file mode 100644 index 0000000000..2ab235993b --- /dev/null +++ b/_contribute_resources/3-code-reviews.md @@ -0,0 +1,8 @@ +--- +title: Code Reviews +link: /contribute/codereviews/ +icon: fa fa-eye +--- +Review pull requests against [scala/scala](https://github.com/scala/scala/pulls), +[scala/scala-lang](https://github.com/scala/scala-lang/pulls), +[scala/scala.github.com](https://github.com/scala/scala.github.com/pulls)and others. \ No newline at end of file diff --git a/_contribute_resources/4-core-libraries.md b/_contribute_resources/4-core-libraries.md new file mode 100644 index 0000000000..7ad75c5752 --- /dev/null +++ b/_contribute_resources/4-core-libraries.md @@ -0,0 +1,6 @@ +--- +title: Core Libraries +link: /contribute/corelibs/ +icon: fa fa-clipboard +--- +Update and expand the capabilities of the core (and associated) Scala libraries. \ No newline at end of file diff --git a/_contribute_resources/5-ide-and-build-tools.md b/_contribute_resources/5-ide-and-build-tools.md new file mode 100644 index 0000000000..4b8bd2ed52 --- /dev/null +++ b/_contribute_resources/5-ide-and-build-tools.md @@ -0,0 +1,6 @@ +--- +title: IDE and Build Tools +link: /contribute/tools/ +icon: fa fa-terminal +--- +Enhance the Scala tools with features for build tools, IDE plug-ins and other related projects. \ No newline at end of file diff --git a/_contribute_resources/6-compiler-language.md b/_contribute_resources/6-compiler-language.md new file mode 100644 index 0000000000..0c4eaa1325 --- /dev/null +++ b/_contribute_resources/6-compiler-language.md @@ -0,0 +1,6 @@ +--- +title: Compiler/Language +link: /contribute/guide/#larger-changes-new-features +icon: fa fa-gears +--- +Larger language features and compiler enhancements including language specification and SIPs. \ No newline at end of file diff --git a/contribute/index.md b/contribute/index.md index dcc78e8149..e843ef2f02 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -25,84 +25,14 @@ how to efficiently report a bug. Coordination of contribution efforts takes place on the [scala-internals Google group](./scala-internals.html). -
-
- -
-

Bug Fixes

-

Issues with the tools, core libraries and compiler. Also you can help us by reporting bugs

-
-
- -
-
-

Code Reviews

-

Review pull requests against scala/scala, -scala/scala-lang, -scala/scala.github.com and others.

-
-
-

Core Libraries

-

Update and expand the capabilities of the core (and associated) Scala libraries.

-
-
- -
-
-

IDE and Build Tools

-

Enhance the Scala tools with features for build tools, IDE plug-ins and other related projects.

-
-
-

Compiler/Language

-

Larger language features and compiler enhancements including language specification and SIPs.

-
-
-
+{% include column-list-of-items.html collection=site.contribute_resources %} ### Community Tickets The following links provide starting points for various contributor activities: -
-
-
-

Documentation

-

Help augment or correct the documentation.

-
-
-

Core Libraries

-

Community bugs and enhancements on the core libs.

-
-
- -
-
-

Tools

-

Help with the Scala tool chain.

-
-
-

Compiler

-

Ready for a challenge? Here's the compiler bugs.

-
-
- -
-
-

Bugs

-

All bugs marked with the label community.

-
-
-

All Issues

-

Bugs + Enhancements marked with the label community.

-
-
-
+{% include column-list-of-items.html collection=site.contribute_community_tickets %} ### Tools and Libraries diff --git a/contribute/tools.md b/contribute/tools.md index 876ce88c1c..420579913e 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -3,6 +3,90 @@ title: IDE and Build Tool Contributions layout: inner-page-no-masthead permalink: /contribute/tools/ includeTOC: true + +# Projects list: +projects: + - title: sbt + description: Interactive build tool. + icon: http://www.scala-sbt.org/assets/typesafe_sbt_svg.svg + link: https://github.com/sbt/sbt + homeLink: http://www.scala-sbt.org/ + issuesLink: https://github.com/sbt/sbt#issues-and-pull-requests + readmeLink: https://github.com/sbt/sbt/blob/0.13/README.md + contributingLink: https://github.com/sbt/sbt/blob/0.13/CONTRIBUTING.md + - title: Scaladoc Tool + description: (Contribute through scala/scala) + icon: https://avatars1.githubusercontent.com/u/57059?v=3&s=200 + link: https://github.com/scala/scala + homeLink: http://www.scala-lang.org/api + issuesLink: https://issues.scala-lang.org/issues/?jql=status%20%3D%20Open%20AND%20component%20%3D%20%22Scaladoc%20Tool%22 + readmeLink: https://github.com/scala/scala#welcome + contributingLink: http://scala-lang.org/contribute/guide.html + - title: Scala IDE + description: Interactive build tool. + icon: https://avatars2.githubusercontent.com/u/1026788?v=3&s=200 + link: https://github.com/scala-ide/scala-ide + homeLink: http://scala-ide.org/ + issuesLink: http://scala-ide-portfolio.assembla.com/spaces/scala-ide/support/tickets + readmeLink: https://github.com/scala-ide/scala-ide/blob/master/README.md + contributingLink: https://github.com/scala-ide/scala-ide/blob/master/CONTRIBUTING.md + - title: DBuild + description: Multi-project build tool. + icon: https://avatars3.githubusercontent.com/u/784923?v=3&s=200 + link: https://github.com/typesafehub/dbuild + homeLink: http://typesafehub.github.io/dbuild + issuesLink: https://github.com/typesafehub/dbuild/issues + readmeLink: https://github.com/typesafehub/dbuild/blob/master/README.md + contributingLink: https://github.com/typesafehub/dbuild/blob/master/README.md#get-involved + - title: Partest + description: Scala Compiler/Library Testing + icon: https://avatars1.githubusercontent.com/u/57059?v=3&s=200 + link: https://github.com/scala/scala-partest + homeLink: http://docs.scala-lang.org/tutorials/partest-guide.html + issuesLink: https://github.com/scala/scala-partest/issues + readmeLink: https://github.com/scala/scala-partest/blob/master/README.md + contributingLink: + - title: Ensime + description: Scala Support for Text Editors + icon: https://avatars0.githubusercontent.com/u/5089042?v=3&s=200 + link: https://github.com/ensime/ensime-server + homeLink: http://ensime.github.io/ + issuesLink: https://github.com/ensime/ensime-server/issues + readmeLink: https://github.com/ensime/ensime-server/blob/2.0/README.md + contributingLink: https://ensime.github.io/contributing/ + - title: Scoverage + description: Scala code coverage tool + icon: https://avatars1.githubusercontent.com/u/5998302?v=3&s=200 + link: https://github.com/scoverage/scalac-scoverage-plugin + homeLink: http://scoverage.org/ + issuesLink: https://github.com/scoverage/scalac-scoverage-plugin/issues + readmeLink: https://github.com/scoverage/scalac-scoverage-plugin/blob/master/README.md + contributingLink: https://groups.google.com/forum/#!forum/scala-code-coverage-tool + - title: Abide + description: Lint tooling for Scala + icon: https://avatars1.githubusercontent.com/u/57059?v=3&s=200 + link: https://github.com/scala/scala-abide + homeLink: https://github.com/scala/scala-abide#abide--lint-tooling-for-scala + issuesLink: https://github.com/scala/scala-abide/issues + readmeLink: https://github.com/scala/scala-abide/blob/master/README.md + contributingLink: https://github.com/scala/scala-abide#extending-abide + +projectsInNeed: + - title: Scalap + description: Scala Decoder (part of scala/scala) + icon: https://avatars1.githubusercontent.com/u/57059?v=3&s=200 + link: https://github.com/scala/scala + homeLink: + issuesLink: https://issues.scala-lang.org/issues/?jql=status%20%3D%20Open%20AND%20text%20~%20%22scalap%22 + readmeLink: https://github.com/scala/scala#welcome + contributingLink: https://github.com/sbt/sbt/blob/0.13/CONTRIBUTING.md + - title: Scaladoc Tool + description: (Contribute through scala/scala) + icon: /resources/img/white-line.png + link: https://github.com/mdr/scalariform + homeLink: https://github.com/mdr/scalariform/wiki/Command-line-tool + issuesLink: https://github.com/mdr/scalariform/issues + readmeLink: https://github.com/mdr/scalariform/blob/master/README.rst --- ## Contributing to IDE and Build Tools @@ -23,109 +107,10 @@ Stuff changes. Found a broken link or something that needs updating on this page ### Projects -
-
-
-sbt logo -

sbt

-

Interactive build tool.

-

Home | -Issues | -ReadMe | -Contributing

-
-
-scala logo -

Scaladoc Tool

-

(Contribute through scala/scala)

-

Home | -Issues | -ReadMe | -Contributing

-
-
- -
-
-scala IDE logo

Scala IDE

-

The Eclipse Scala IDE project.

-

Home | -Issues | -ReadMe | -Contributing

-
-
-dbuild logo

DBuild

-

Multi-project build tool.

-

Home | -Issues | -ReadMe | -Contributing

-
-
- -
-
-scala logo -

Partest

-

Scala Compiler/Library Testing

-

Home | -Issues | -ReadMe

-
-
-ensime logo

Ensime

-

Scala Support for Text Editors

-

Home | -Issues | -ReadMe | -Contributing

-
-
- -
-
-scoverage logo

Scoverage

-

Scala code coverage tool

-

Home | -Issues | -ReadMe | -Contributing

-
-
-scala logo -

Abide

-

Lint tooling for Scala

-

Home | -Issues | -ReadMe | -Contributing

-
-
-
+{% include contributions-projects-list.html collection=page.projects %} ### Projects in Particular Need The following projects are important to the Scala community but are particularly in need of contributors to continue their development. -
-
-
-scala logo -

Scalap

-

Scala Decoder (part of scala/scala)

-

Issues | -ReadMe | -Contributing

-
-
-white line

Scalariform

-

Scala code formatter

-

Home | -Issues | -ReadMe

-
-
-
- - +{% include contributions-projects-list.html collection=page.projectsInNeed %} \ No newline at end of file From 0aa2f7f9660ea580cc661899ece1f99106f99c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20de=20Sil=C3=B3niz=20Sandino?= Date: Thu, 9 Feb 2017 12:10:38 +0100 Subject: [PATCH 0109/3075] Adding code of conduct --- contribute/index.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contribute/index.md b/contribute/index.md index e843ef2f02..f0c52986b8 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -17,13 +17,13 @@ That depends on what you want to contribute. Below are some getting started reso ### Reporting bugs -See our [bug reporting guide](./bug-reporting-guide.html) to learn +See our [bug reporting guide](/contribute/bug-reporting-guide/) to learn how to efficiently report a bug. ### Contribute Coordination of contribution efforts takes place on the -[scala-internals Google group](./scala-internals.html). +[scala-internals Google group](/contribute/scala-internals/). {% include column-list-of-items.html collection=site.contribute_resources %} @@ -41,7 +41,7 @@ with their own maintainers and community of contributors. Helping out one of these projects is another way to help Scala. Consider lending on a hand on a project you're already using. Or, to find out about other projects, see the -[Libraries and Tools section](../community/#community-libraries-and-tools) +[Libraries and Tools section](/community/#community-libraries-and-tools) on our Community page. ### Scala Community Build From 32684bae5d915d7bcf7ce69c860c2930c5f89d6b Mon Sep 17 00:00:00 2001 From: Janek Bogucki Date: Tue, 20 Jun 2017 10:19:33 +0100 Subject: [PATCH 0110/3075] Update bug reporting links --- contribute/bug-reporting-guide.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contribute/bug-reporting-guide.md b/contribute/bug-reporting-guide.md index 960f40b704..13a7553c88 100644 --- a/contribute/bug-reporting-guide.md +++ b/contribute/bug-reporting-guide.md @@ -3,7 +3,7 @@ layout: page title: Bug Reporting --- -The Scala project tracker is located at [http://issues.scala-lang.org](http://issues.scala-lang.org). Before you submit a bug make sure that it is certainly a bug by following instructions in *Is it a Bug?*. +The Scala compiler and standard library bug tracker is located at [https://github.com/scala/bug](https://github.com/scala/bug). Before you submit a bug make sure that it is certainly a bug by following instructions in *Is it a Bug?*. ## Is it a Bug? @@ -43,12 +43,12 @@ If you have a code snippet that is resulting in bytecode which you believe is be 5. If you want to file an improvement in the issue tracker please discuss it first on one of the mailing lists. They offer much bigger audience than issue tracker. The latter is not suitable for long discussions. -* Keep in mind that the behavior you are witnessing could be intended. Good formal resources for verifying whether or not the language behavior is intended is either in the [Scala Improvement Proposal Documents](http://docs.scala-lang.org/sips/sip-list.html) or in the [Scala Language Specification](http://www.scala-lang.org/files/archive/spec/2.11/). If in doubt, you may always ask on the [scala-internals mailing list](https://groups.google.com/forum/?fromgroups#!forum/scala-internals) or [stackoveflow](http://stackoverflow.com/questions/tagged/scala). +* Keep in mind that the behavior you are witnessing could be intended. Good formal resources for verifying whether or not the language behavior is intended is either in the [Scala Improvement Proposal Documents](http://docs.scala-lang.org/sips/sip-list.html) or in the [Scala Language Specification](http://www.scala-lang.org/files/archive/spec/2.12/). If in doubt, you may always ask on the [Community Category](https://contributors.scala-lang.org/c/community) or [Stack Overflow](https://stackoverflow.com/questions/tagged/scala). -In general, if you find yourself stuck on any of these steps, asking on one of the following Scala mailing lists can be helpful: +In general, if you find yourself stuck on any of these steps, asking on [Scala Contributors](https://contributors.scala-lang.org/) can be helpful: - - For unexpected behavior use [scala-language](https://groups.google.com/forum/?fromgroups#!forum/scala-language), or [scala-user](https://groups.google.com/forum/?fromgroups#!forum/scala-user) mailing lists. - - For compiler bugs use the [scala-internals](https://groups.google.com/forum/?fromgroups#!forum/scala-internals) mailing list. + - For unexpected behavior use the [Community Category](https://contributors.scala-lang.org/c/community). + - For compiler bugs use the [Compiler Category](https://contributors.scala-lang.org/c/compiler). * Examples of exceptions reported by the compiler which usually are not bugs: 1. `StackOverflowError` is typically not a bug unless the stacktrace involves the internal packages of the compiler (like `scala.tools.nsc...`). Try to increase the Java stack size (`-Xss`), in most of the cases it helps. @@ -84,4 +84,4 @@ In the description of your issue, be as detailed as you can. Bug reports which h 2. The expected output. 3. The actual output, including the stacktrace. 4. Related discussion on the mailing lists, if applicable. - 4. If you have already looked into the issue provide interesting insights or proposals for fixing the issue. + 5. If you have already looked into the issue provide interesting insights or proposals for fixing the issue. From 7390eec1410fbd55523e919450ef8dda1ffa6c87 Mon Sep 17 00:00:00 2001 From: Janek Bogucki Date: Thu, 22 Jun 2017 10:21:22 +0100 Subject: [PATCH 0111/3075] Add scalacheck tips and note removal of partest --- contribute/hacker-guide.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 8d7903fbea..a8e9d2e14c 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -264,11 +264,13 @@ Adding tests to the test suite is as easy as moving them to the appropriate dire * Code which should not compile needs to go into the [“neg” directory](https://github.com/scala/scala/tree/2.12.x/test/files/neg). * Code which should compile and get executed by the test suite needs to go into the [“run” directory](https://github.com/scala/scala/tree/2.12.x/test/files/run) and have a corresponding `.check` file with the expected output. You will get test failures if the content of a `.check` file is different from what the test produces while running. If the change in the output is an expected product of your work, you might not want to change the `.check` file by hand. To make partest change the `.check` file, run it with a `--update-check` flag, like so `./test/partest --update-check path/to/test.scala`. For more information on partest, please refer to its [documentation](http://docs.scala-lang.org/tutorials/partest-guide.html). * Everything that can be unit-tested should go to ["junit" directory](https://github.com/scala/scala/tree/2.12.x/test/junit) -* Property-based tests go to the ["scalacheck" directory](https://github.com/scala/scala/tree/2.12.x/test/files/scalacheck) +* Property-based tests go to the ["scalacheck" directory](https://github.com/scala/scala/tree/2.12.x/test/scalacheck) Here are some more testing tips: -* If you have several tests, and want a tool for only running tests that conform to some regular expression, you can use `partest-ack` in the `tools` directory: `./tools/partest-ack "dottype"` +* If you have several tests, and want a tool for only running tests that conform to some regular expression, you can use `partest-ack` in the `tools` directory: `./tools/partest-ack "dottype"`. `partest-ack` was removed in 2.12. +* If you want to run all scalacheck tests from sbt use `scalacheck/testOnly` +* To run scalacheck tests by name when in sbt use `scalacheck/testOnly ... `, for example `scalacheck/testOnly scala.tools.nsc.scaladoc.HtmlFactoryTest` * If your tests fail in the following way: test.bc: @@ -320,6 +322,8 @@ Run `sbt test` and `sbt partest` to run all of the JUnit and partest tests, resp testing: [...]/files/run/stringinterpolation_macro-run.scala [ OK ] All of 6 tests were successful (elapsed time: 00:00:08) +`partest` was removed in 2.12. + ## 4. Publish After development is finished, it's time to publish the code and submit your patch for discussion and potential inclusion into Scala. From c8305a9b4e7279273842e2701bfdb649a872ab88 Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Thu, 13 Jul 2017 17:23:15 +0200 Subject: [PATCH 0112/3075] Get rid of some of the permalinks that are breaking everything --- contribute/bug-reporting-guide.md | 2 +- contribute/codereviews.md | 8 ++--- contribute/corelibs.md | 6 ++-- contribute/documentation.md | 20 ++++++------- contribute/guide.md | 6 ++-- contribute/hacker-guide.md | 4 +-- contribute/index.md | 4 +-- contribute/partest-guide.md | 30 +++++++++---------- contribute/scala-internals.md | 5 ++-- ...cala-standard-library-api-documentation.md | 2 +- contribute/tools.md | 10 +++---- 11 files changed, 48 insertions(+), 49 deletions(-) diff --git a/contribute/bug-reporting-guide.md b/contribute/bug-reporting-guide.md index 33b61807c2..05569ff8e4 100644 --- a/contribute/bug-reporting-guide.md +++ b/contribute/bug-reporting-guide.md @@ -1,7 +1,7 @@ --- title: Bug Reporting layout: inner-page-no-masthead -permalink: /contribute/bug-reporting-guide/ +# permalink: /contribute/bug-reporting-guide/ includeTOC: true --- diff --git a/contribute/codereviews.md b/contribute/codereviews.md index 9239fa8c14..2c56b4ed37 100644 --- a/contribute/codereviews.md +++ b/contribute/codereviews.md @@ -1,18 +1,18 @@ --- title: Code Review Contributions layout: inner-page-no-masthead -permalink: /contribute/codereviews/ +# permalink: /contribute/codereviews/ includeTOC: true --- ## Code Review Contributions -In addition to [bug fixing](/contribute/guide/), you can help us review -[waiting pull requests](#pull-requests-awaiting-comment). +In addition to [bug fixing](/contribute/guide/), you can help us review +[waiting pull requests](#pull-requests-awaiting-comment). This is also a good (and recommended) way to get to know the feel of the bug-fixing and submissions process before jumping in with your own pull requests. - + ### Review Guidelines [Code of Conduct reminder](/conduct/) diff --git a/contribute/corelibs.md b/contribute/corelibs.md index 1f34d150b0..fd69ae196e 100644 --- a/contribute/corelibs.md +++ b/contribute/corelibs.md @@ -1,7 +1,7 @@ --- title: Core Library Contributions layout: inner-page-no-masthead -permalink: /contribute/corelibs/ +# permalink: /contribute/corelibs/ includeTOC: true --- ## Core Library Contributions @@ -10,14 +10,14 @@ There are several options for contributing to Scala's core libraries. You can: * Help with [Documentation](/contribute/scala-standard-library-api-documentation/). * [Report Bugs or Issues](/contribute/bug-reporting-guide/) against the core libraries. -* [Fix Bugs or Issues](/contribute/guide/) against the +* [Fix Bugs or Issues](/contribute/guide/) against the [reported library bugs/issues](https://issues.scala-lang.org/issues/?filter=13001). * Contribute significant new functionality or a new API by submitting a Scala Library Improvement Process (SLIP) Document. ### Submitting a SLIP -For significant new functionality or a whole new API to be considered for +For significant new functionality or a whole new API to be considered for inclusion in the core Scala distribution, you will be asked to submit a SLIP (Scala Library Improvement Process) document. Please see [instructions for submitting a new SLIP](http://docs.scala-lang.org/sips/slip-submission.html) and familiarize yourself with the [SIP/SLIP](http://docs.scala-lang.org/sips/) section of the Scala documentation site. Also please pay particular attention to the [pre-requisites](http://docs.scala-lang.org/sips/slip-submission.html) before submitting a SLIP. diff --git a/contribute/documentation.md b/contribute/documentation.md index 2746fa77dc..8930a3c32c 100644 --- a/contribute/documentation.md +++ b/contribute/documentation.md @@ -1,7 +1,7 @@ --- title: Documentation Contributions layout: inner-page-no-masthead -permalink: /contribute/documentation/ +# permalink: /contribute/documentation/ includeTOC: true --- ## Contributing Documentation to the Scala project @@ -14,7 +14,7 @@ There are several ways you can help out with the improvement of Scala documentat Please read this page, and the pages linked from this one, fully before contributing documentation. Many of the questions you have will be answered in these resources. If you have a question that isn't answered, feel free to ask on the [scala-internals Google group](https://groups.google.com/forum/#!forum/scala-internals) and then, please, submit a pull request with updated documentation reflecting that answer. -**General requirements** for documentation submissions include spell-checking all written language, ensuring code samples compile and run correctly, correct grammar, and clean formatting/layout of the documentation. +**General requirements** for documentation submissions include spell-checking all written language, ensuring code samples compile and run correctly, correct grammar, and clean formatting/layout of the documentation. Thanks @@ -22,12 +22,12 @@ Thanks The Scala API documentation lives with the scala project source code. There are many ways you can help with improving Scaladoc, including: -* [Log issues for missing scaladoc documentation](/contribute/scala-standard-library-api-documentation/#contribute-api-documentation-bug-reports) - +* [Log issues for missing scaladoc documentation](/contribute/scala-standard-library-api-documentation/#contribute-api-documentation-bug-reports) - Please *follow the issue submission process closely* to help prevent duplicate issues being created. * [Claim Scaladoc Issues and Provide Documentation](/contribute/scala-standard-library-api-documentation/) - please claim issues prior to working on a specific scaladoc task to prevent duplication of effort. If you sit on an issue for too long without submitting a pull request, it will revert back to unassigned and you will need to re-claim it. -* You can also just -[submit new Scaladoc](/contribute/scala-standard-library-api-documentation/) -without creating an issue, but please look to see if there is an issue already submitted for your task and claim it if there is. If not, please post your intention to work on a specific scaladoc task on scala-internals so that people know what you are doing. +* You can also just +[submit new Scaladoc](/contribute/scala-standard-library-api-documentation/) +without creating an issue, but please look to see if there is an issue already submitted for your task and claim it if there is. If not, please post your intention to work on a specific scaladoc task on scala-internals so that people know what you are doing. ### The Main Scala Documentation Site @@ -43,15 +43,15 @@ without creating an issue, but please look to see if there is an issue already s * SIP (Scala Improvement Process) Proposals and more -Please read [contributing to the docs.scala-lang.org site](http://docs.scala-lang.org/contribute.html) through before embarking on changes. The site uses +Please read [contributing to the docs.scala-lang.org site](http://docs.scala-lang.org/contribute.html) through before embarking on changes. The site uses the [Jekyll](http://jekyllrb.com/) markdown engine so you will need to follow the instructions to get that running as well. ### Updating scala-lang.org Additional high-level documentation (including documentation on contributing -to Scala and related projects) is provided on the main -[Scala Language site](http://scala-lang.org), and is also kept in the -[scala-lang github project](https://github.com/scala/scala-lang) which may be forked to create pull requests. +to Scala and related projects) is provided on the main +[Scala Language site](http://scala-lang.org), and is also kept in the +[scala-lang github project](https://github.com/scala/scala-lang) which may be forked to create pull requests. Please read both the [docs.scala-lang.org contribution](http://docs.scala-lang.org/contribute.html) document and the [scala-lang.org github README](https://github.com/scala/scala-lang#scala-langorg) before embarking on any changes to the Scala language site, as it uses the same Jekyll markdown tool and many of the same conventions as the Scala documentation site. diff --git a/contribute/guide.md b/contribute/guide.md index afd3572c53..9edb289e06 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -1,7 +1,7 @@ --- title: Contributing guide layout: inner-page-no-masthead -permalink: /contribute/guide/ +# permalink: /contribute/guide/ includeTOC: true --- @@ -54,9 +54,9 @@ unencumbered by copyrights or patents. This is the impatient developer's checklist for the steps to submit a bug-fix pull request to the Scala project. For more information, description and justification for the steps, follow the links in that step. Further specific instructions for the release of Scala you are targeting can be found in the `CONTRIBUTING.md` file for that [github branch](https://github.com/scala/scala) -1. [Select a bug to fix from JIRA](/contribute/#community-tickets), or if you found the bug yourself and want to fix it, [create a JIRA issue](/contribute/bug-reporting-guide/) (but please +1. [Select a bug to fix from JIRA](/contribute/#community-tickets), or if you found the bug yourself and want to fix it, [create a JIRA issue](/contribute/bug-reporting-guide/) (but please [make sure it's not a duplicate](/contribute/bug-reporting-guide/#reporting-confirmed-bugs-is-a-sin)). -2. Optional ([but recommended](/contribute/scala-internals/#why-its-a-good-idea)), announce your intention to work on the bug on [scala-internals](/contribute/scala-internals/). After all, don't you want to work on a team with +2. Optional ([but recommended](/contribute/scala-internals/#why-its-a-good-idea)), announce your intention to work on the bug on [scala-internals](/contribute/scala-internals/). After all, don't you want to work on a team with [these friendly people](/contribute/hacker-guide/#connect) - it's one of the perks of contributing. 3. [Fork the Scala repository](/contribute/hacker-guide/#fork) and clone your fork (if you haven't already). 4. [Create a feature branch](/contribute/hacker-guide/#branch) to work on: use the branch name `issue/NNNN` where NNNN is the JIRA issue number. diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index abfe59b2da..31602a0909 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -2,7 +2,7 @@ title: Scala hacker guide by: Eugene Burmako layout: inner-page-no-masthead -permalink: /contribute/hacker-guide/ +# permalink: /contribute/hacker-guide/ includeTOC: true ---
@@ -54,7 +54,7 @@ it probably makes sense to familiarize yourself with Git first. We recommend * the [Git Pro](http://git-scm.com/book/en/) online book. * the help page on [Forking a Git Repository](https://help.github.com/articles/fork-a-repo). -* this great training tool [LearnGitBranching](http://pcottle.github.io/learnGitBranching/). One hour hands-on training helps more than 1000 hours reading. +* this great training tool [LearnGitBranching](http://pcottle.github.io/learnGitBranching/). One hour hands-on training helps more than 1000 hours reading. ### Fork diff --git a/contribute/index.md b/contribute/index.md index f0c52986b8..3dac16ead4 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -1,7 +1,7 @@ --- title: Contribute layout: inner-page-no-masthead -permalink: /contribute/ +# permalink: /contribute/ includeTOC: true --- @@ -22,7 +22,7 @@ how to efficiently report a bug. ### Contribute -Coordination of contribution efforts takes place on the +Coordination of contribution efforts takes place on the [scala-internals Google group](/contribute/scala-internals/). {% include column-list-of-items.html collection=site.contribute_resources %} diff --git a/contribute/partest-guide.md b/contribute/partest-guide.md index be37d6fc12..ce4f84ecf1 100644 --- a/contribute/partest-guide.md +++ b/contribute/partest-guide.md @@ -1,7 +1,7 @@ --- title: Running the Test Suite layout: inner-page-no-masthead -permalink: /contribute/partest-guide/ +# permalink: /contribute/partest-guide/ includeTOC: true --- @@ -14,11 +14,11 @@ The test suite can be run by using ant from the command line: $ ant test.suite ## Standalone - -There are launch scripts `partest` and `partest.bat` in the `test` folder of the scala project. To have partest run failing tests only and print details about test failures to the console, you can use - + +There are launch scripts `partest` and `partest.bat` in the `test` folder of the scala project. To have partest run failing tests only and print details about test failures to the console, you can use + ./test/partest --show-diff --show-log --failed - + You can get a summary of the usage by running partest without arguments. * Most commonly you want to invoke partest with an option that tells it which part of the tests to run. For example `--all`, `--pos`, `--neg` or `--run`. @@ -29,13 +29,13 @@ You can get a summary of the usage by running partest without arguments. * You can use the `SCALAC_OPTS` environment variable to pass command line options to the compiler. * You can use the `JAVA_OPTS` environment variable to pass command line options to the runner (e.g., for `run/jvm` tests). * The launch scripts run partest as follows: - + scala -cp scala.tools.partest.nest.NestRunner - + Partest classes from a `quick` build, e.g., can be found in `./build/quick/classes/partest/`. - + Partest will tell you where it loads compiler/library classes from by adding the `partest.debug` property: - + scala -Dpartest.debug=true -cp scala.tools.partest.nest.NestRunner @@ -46,10 +46,10 @@ Tests that depend on [ScalaCheck](https://github.com/rickynils/scalacheck) can b import org.scalacheck._ import Prop._ - + object Test { val prop_ConcatLists = property{ (l1: ListInt, l2: ListInt) => - l1.size + l2.size == (l1 ::: l2).size + l1.size + l2.size == (l1 ::: l2).size } val tests = List(("prop_ConcatLists", prop_ConcatLists)) @@ -59,10 +59,10 @@ Tests that depend on [ScalaCheck](https://github.com/rickynils/scalacheck) can b ### Windows -Some tests might fail because line endings in the `.check` files and the produced results do not match. In that case, set either +Some tests might fail because line endings in the `.check` files and the produced results do not match. In that case, set either - git config core.autocrlf false + git config core.autocrlf false -or +or - git config core.autocrlf input \ No newline at end of file + git config core.autocrlf input diff --git a/contribute/scala-internals.md b/contribute/scala-internals.md index 831f2cc864..e6fde53a81 100644 --- a/contribute/scala-internals.md +++ b/contribute/scala-internals.md @@ -7,11 +7,11 @@ includeTOC: true ## scala-internals -The [scala-internals mailing list](https://groups.google.com/d/forum/scala-internals) is where technical and logistical discussions concerning bugs, bug fixes, documentation, improvements, new features and other contributor related topics occur. +The [scala-internals mailing list](https://groups.google.com/d/forum/scala-internals) is where technical and logistical discussions concerning bugs, bug fixes, documentation, improvements, new features and other contributor related topics occur. ### Coordinating on scala-internals -Prior to commencing on contribution work on larger changes to the Scala project, it is recommended (but not required) that you make a post on scala-internals announcing your intention. It's a great time to invite any help, advice or ask any questions you might have. It's also a great place to meet peers, one of whom will probably be reviewing your contribution at some point. For smaller bug fixes or documentation changes where the risk of effort duplication is minimal, you can skip this post. +Prior to commencing on contribution work on larger changes to the Scala project, it is recommended (but not required) that you make a post on scala-internals announcing your intention. It's a great time to invite any help, advice or ask any questions you might have. It's also a great place to meet peers, one of whom will probably be reviewing your contribution at some point. For smaller bug fixes or documentation changes where the risk of effort duplication is minimal, you can skip this post. To help subscribers on the scala-internals list to sort through the postings, we request that the following topic labels are applied when you start a new post please: @@ -44,4 +44,3 @@ While it is optional to announce your intentions/work items on scala-internals b * There are a lot of nice people waiting to talk to you on scala-internals, you might be surprised how valuable and pleasant you find the experience of talking to them. If all of this has not convinced you then, please, go ahead and work on contributions anyway. It *is* less important to post to scala-internals first for small, self contained bugs than it is for larger issues or features, and not having posted first will not be a reason for your PR to be rejected, it just might be a rougher review/merge process than if you had posted first. It's your choice. - diff --git a/contribute/scala-standard-library-api-documentation.md b/contribute/scala-standard-library-api-documentation.md index 68df995375..c64a176cde 100644 --- a/contribute/scala-standard-library-api-documentation.md +++ b/contribute/scala-standard-library-api-documentation.md @@ -1,7 +1,7 @@ --- title: Contribute to API Documentation layout: inner-page-no-masthead -permalink: /contribute/scala-standard-library-api-documentation/ +# permalink: /contribute/scala-standard-library-api-documentation/ includeTOC: true --- diff --git a/contribute/tools.md b/contribute/tools.md index 420579913e..de96e19fa5 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -1,7 +1,7 @@ --- title: IDE and Build Tool Contributions layout: inner-page-no-masthead -permalink: /contribute/tools/ +# permalink: /contribute/tools/ includeTOC: true # Projects list: @@ -45,7 +45,7 @@ projects: homeLink: http://docs.scala-lang.org/tutorials/partest-guide.html issuesLink: https://github.com/scala/scala-partest/issues readmeLink: https://github.com/scala/scala-partest/blob/master/README.md - contributingLink: + contributingLink: - title: Ensime description: Scala Support for Text Editors icon: https://avatars0.githubusercontent.com/u/5089042?v=3&s=200 @@ -76,7 +76,7 @@ projectsInNeed: description: Scala Decoder (part of scala/scala) icon: https://avatars1.githubusercontent.com/u/57059?v=3&s=200 link: https://github.com/scala/scala - homeLink: + homeLink: issuesLink: https://issues.scala-lang.org/issues/?jql=status%20%3D%20Open%20AND%20text%20~%20%22scalap%22 readmeLink: https://github.com/scala/scala#welcome contributingLink: https://github.com/sbt/sbt/blob/0.13/CONTRIBUTING.md @@ -103,7 +103,7 @@ if you would like to help revive them. ### Broken Links? -Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](/contribute/documentation/#updating-scala-langorg) to fix it. +Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](/contribute/documentation/#updating-scala-langorg) to fix it. ### Projects @@ -113,4 +113,4 @@ Stuff changes. Found a broken link or something that needs updating on this page The following projects are important to the Scala community but are particularly in need of contributors to continue their development. -{% include contributions-projects-list.html collection=page.projectsInNeed %} \ No newline at end of file +{% include contributions-projects-list.html collection=page.projectsInNeed %} From fbca9ca0b3ef20fbb657aa132f88f85b097607b4 Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Fri, 14 Jul 2017 17:02:30 +0200 Subject: [PATCH 0113/3075] Bug reporting guide link fixes --- _contribute_resources/2-bug-fixes.md | 2 +- contribute/corelibs.md | 2 +- contribute/guide.md | 6 +++--- contribute/index.md | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/_contribute_resources/2-bug-fixes.md b/_contribute_resources/2-bug-fixes.md index d10adb7908..8661ab9614 100644 --- a/_contribute_resources/2-bug-fixes.md +++ b/_contribute_resources/2-bug-fixes.md @@ -3,4 +3,4 @@ title: Bug fixes link: /contribute/guide/ icon: fa fa-pencil --- -Issues with the tools, core libraries and compiler. Also you can help us by [reporting bugs](/contribute/bug-reporting-guide/). \ No newline at end of file +Issues with the tools, core libraries and compiler. Also you can help us by [reporting bugs](/contribute/bug-reporting-guide.html). diff --git a/contribute/corelibs.md b/contribute/corelibs.md index fd69ae196e..c06a741915 100644 --- a/contribute/corelibs.md +++ b/contribute/corelibs.md @@ -9,7 +9,7 @@ includeTOC: true There are several options for contributing to Scala's core libraries. You can: * Help with [Documentation](/contribute/scala-standard-library-api-documentation/). -* [Report Bugs or Issues](/contribute/bug-reporting-guide/) against the core libraries. +* [Report Bugs or Issues](/contribute/bug-reporting-guide.html) against the core libraries. * [Fix Bugs or Issues](/contribute/guide/) against the [reported library bugs/issues](https://issues.scala-lang.org/issues/?filter=13001). * Contribute significant new functionality or a new API by submitting diff --git a/contribute/guide.md b/contribute/guide.md index 9edb289e06..bda4fa9ff3 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -12,7 +12,7 @@ includeTOC: true

Get a peek into the inners of the Scala compiler.

-

Report an issue

+

Report an issue

File a bug report or a feature request.

@@ -54,8 +54,8 @@ unencumbered by copyrights or patents. This is the impatient developer's checklist for the steps to submit a bug-fix pull request to the Scala project. For more information, description and justification for the steps, follow the links in that step. Further specific instructions for the release of Scala you are targeting can be found in the `CONTRIBUTING.md` file for that [github branch](https://github.com/scala/scala) -1. [Select a bug to fix from JIRA](/contribute/#community-tickets), or if you found the bug yourself and want to fix it, [create a JIRA issue](/contribute/bug-reporting-guide/) (but please -[make sure it's not a duplicate](/contribute/bug-reporting-guide/#reporting-confirmed-bugs-is-a-sin)). +1. [Select a bug to fix from JIRA](/contribute/#community-tickets), or if you found the bug yourself and want to fix it, [create a JIRA issue](/contribute/bug-reporting-guide.html) (but please +[make sure it's not a duplicate](/contribute/bug-reporting-guide.html#reporting-confirmed-bugs-is-a-sin)). 2. Optional ([but recommended](/contribute/scala-internals/#why-its-a-good-idea)), announce your intention to work on the bug on [scala-internals](/contribute/scala-internals/). After all, don't you want to work on a team with [these friendly people](/contribute/hacker-guide/#connect) - it's one of the perks of contributing. 3. [Fork the Scala repository](/contribute/hacker-guide/#fork) and clone your fork (if you haven't already). diff --git a/contribute/index.md b/contribute/index.md index 3dac16ead4..55563f8ac0 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -17,7 +17,7 @@ That depends on what you want to contribute. Below are some getting started reso ### Reporting bugs -See our [bug reporting guide](/contribute/bug-reporting-guide/) to learn +See our [bug reporting guide](/contribute/bug-reporting-guide.html) to learn how to efficiently report a bug. ### Contribute From e2f7c0712662e555f53f7c77cee608b5aadee722 Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Fri, 14 Jul 2017 17:06:56 +0200 Subject: [PATCH 0114/3075] Removing some mentions of scala-internals --- contribute/documentation.md | 4 ++-- contribute/guide.md | 6 +++--- contribute/hacker-guide.md | 6 +++--- contribute/index.md | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/contribute/documentation.md b/contribute/documentation.md index 8930a3c32c..0111c5c15d 100644 --- a/contribute/documentation.md +++ b/contribute/documentation.md @@ -12,7 +12,7 @@ There are several ways you can help out with the improvement of Scala documentat * Guides, Overviews, Tutorials, Cheat Sheets and more on the docs.scala-lang.org site * Updating scala-lang.org -Please read this page, and the pages linked from this one, fully before contributing documentation. Many of the questions you have will be answered in these resources. If you have a question that isn't answered, feel free to ask on the [scala-internals Google group](https://groups.google.com/forum/#!forum/scala-internals) and then, please, submit a pull request with updated documentation reflecting that answer. +Please read this page, and the pages linked from this one, fully before contributing documentation. Many of the questions you have will be answered in these resources. If you have a question that isn't answered, feel free to ask on the [Scala Contributors](https://contributors.scala-lang.org/) mailing list and then, please, submit a pull request with updated documentation reflecting that answer. **General requirements** for documentation submissions include spell-checking all written language, ensuring code samples compile and run correctly, correct grammar, and clean formatting/layout of the documentation. @@ -27,7 +27,7 @@ Please *follow the issue submission process closely* to help prevent duplicate i * [Claim Scaladoc Issues and Provide Documentation](/contribute/scala-standard-library-api-documentation/) - please claim issues prior to working on a specific scaladoc task to prevent duplication of effort. If you sit on an issue for too long without submitting a pull request, it will revert back to unassigned and you will need to re-claim it. * You can also just [submit new Scaladoc](/contribute/scala-standard-library-api-documentation/) -without creating an issue, but please look to see if there is an issue already submitted for your task and claim it if there is. If not, please post your intention to work on a specific scaladoc task on scala-internals so that people know what you are doing. +without creating an issue, but please look to see if there is an issue already submitted for your task and claim it if there is. If not, please post your intention to work on a specific scaladoc task on [Scala Contributors](https://contributors.scala-lang.org/) so that people know what you are doing. ### The Main Scala Documentation Site diff --git a/contribute/guide.md b/contribute/guide.md index bda4fa9ff3..a824e2297f 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -8,7 +8,7 @@ includeTOC: true
-

Scala Internals

+

Scala Contributors

Get a peek into the inners of the Scala compiler.

@@ -56,7 +56,7 @@ This is the impatient developer's checklist for the steps to submit a bug-fix pu 1. [Select a bug to fix from JIRA](/contribute/#community-tickets), or if you found the bug yourself and want to fix it, [create a JIRA issue](/contribute/bug-reporting-guide.html) (but please [make sure it's not a duplicate](/contribute/bug-reporting-guide.html#reporting-confirmed-bugs-is-a-sin)). -2. Optional ([but recommended](/contribute/scala-internals/#why-its-a-good-idea)), announce your intention to work on the bug on [scala-internals](/contribute/scala-internals/). After all, don't you want to work on a team with +2. Optional ([but recommended](/contribute/scala-internals/#why-its-a-good-idea)), announce your intention to work on the bug on [Scala Contributors](https://contributors.scala-lang.org/). After all, don't you want to work on a team with [these friendly people](/contribute/hacker-guide/#connect) - it's one of the perks of contributing. 3. [Fork the Scala repository](/contribute/hacker-guide/#fork) and clone your fork (if you haven't already). 4. [Create a feature branch](/contribute/hacker-guide/#branch) to work on: use the branch name `issue/NNNN` where NNNN is the JIRA issue number. @@ -75,7 +75,7 @@ Need more information or a little more hand-holding for the first one? We got yo For larger, more ambitious changes (e.g. new language features), the first step to making a change is to discuss it with the community at large, to make sure everyone agrees on the idea and on the implementation plan. Announce the change -on the [scala-internals](http://groups.google.com/group/scala-internals) mailing list and get developer feedback. For really complex changes, a [Scala Improvement Process (SIP)](http://docs.scala-lang.org/sips/) document might be required, but the first step is always to discuss it on the mailing list and if a SIP is required, that will be discussed on the mailing list. +on the [Scala Contributors](https://contributors.scala-lang.org/) mailing list and get developer feedback. For really complex changes, a [Scala Improvement Process (SIP)](http://docs.scala-lang.org/sips/) document might be required, but the first step is always to discuss it on the mailing list and if a SIP is required, that will be discussed on the mailing list. Contributions, big or small, simple or complex, controversial or undisputed, need to materialize as patches against the Scala project source tree. The [hacker guide](/contribute/hacker-guide/) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 31602a0909..a10fbb70eb 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -38,7 +38,7 @@ A list of language features/libraries along with their maintainer's full names a In our running example, since Martin is the person who submitted the string interpolation Scala Improvement Proposal and implemented this language feature for Scala 2.10.0, he might be interested in learning of new bugfixes to that feature. -As alluded to earlier, one must also choose an appropriate mailing list. Typically, one would use the scala-internals mailing list, as it is devoted to discussions about the core internal design and implementation of the Scala system. However, since this issue has been discussed previously on the scala-user mailing list, +As alluded to earlier, one must also choose an appropriate mailing list. Typically, one would use the [Scala Contributors](https://contributors.scala-lang.org/) mailing list, as it is devoted to discussions about the core internal design and implementation of the Scala system. However, since this issue has been discussed previously on the scala-user mailing list, in this example, we post to the [the scala-user mailing list](http://groups.google.com/group/scala-user) about our issue. Posting to scala-user @@ -202,7 +202,7 @@ If you intend on contributing to Scala collections, please make sure you're fami ##### The Scala Compiler -Documentation about the internal workings of the Scala compiler is scarce, and most of the knowledge is passed around by email (scala-internals mailing list), ticket, or word of mouth. However the situation is steadily improving. Here are the resources that might help: +Documentation about the internal workings of the Scala compiler is scarce, and most of the knowledge is passed around by email ([Scala Contributors](https://contributors.scala-lang.org/) mailing list), ticket, or word of mouth. However the situation is steadily improving. Here are the resources that might help: * [Compiler internals videos by Martin Odersky](http://www.scala-lang.org/old/node/598.html) are quite dated, but still very useful. In this three-video series Martin explains the general architecture of the compiler, and the basics of the front-end, which has recently become Scala reflection API. @@ -212,7 +212,7 @@ Documentation about the internal workings of the Scala compiler is scarce, and m at Lang.NEXT 2012 in which Martin elaborates on the design of scalac and the architecture of the reflection API. * [Scala compiler corner](http://lampwww.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/) contains extensive documentation about most of the post-typer phases (i.e. the backend) in the Scala compiler. -* [scala-internals](http://groups.google.com/group/scala-internals), a mailing list which hosts discussions about the core +* [Scala Contributors](https://contributors.scala-lang.org/), a mailing list which hosts discussions about the core internal design and implementation of the Scala system. ##### Other Projects diff --git a/contribute/index.md b/contribute/index.md index 55563f8ac0..f56a91c163 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -22,8 +22,8 @@ how to efficiently report a bug. ### Contribute -Coordination of contribution efforts takes place on the -[scala-internals Google group](/contribute/scala-internals/). +Coordination of contribution efforts takes place on +[Scala Contributors](https://contributors.scala-lang.org/). {% include column-list-of-items.html collection=site.contribute_resources %} From 5c3fbae7f06170f21acc05a37f278cacc84bdb8d Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Fri, 14 Jul 2017 17:08:59 +0200 Subject: [PATCH 0115/3075] Missing whitespace --- _contribute_resources/1-documentation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_contribute_resources/1-documentation.md b/_contribute_resources/1-documentation.md index 27739dee6a..0d9c198ffd 100644 --- a/_contribute_resources/1-documentation.md +++ b/_contribute_resources/1-documentation.md @@ -3,4 +3,4 @@ title: Documentation link: /contribute/documentation/ icon: fa fa-file-text --- -[Scaladoc (API)](/contribute/scala-standard-library-api-documentation/),[docs.scala-lang.org](http://docs.scala-lang.org/contribute.html) and [scala-lang.org](https://github.com/scala/scala-lang). \ No newline at end of file +[Scaladoc (API)](/contribute/scala-standard-library-api-documentation/), [docs.scala-lang.org](http://docs.scala-lang.org/contribute.html) and [scala-lang.org](https://github.com/scala/scala-lang). From d1d0f26798c64d560e8795343b49db234c7b0969 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Wed, 19 Jul 2017 11:29:38 -0400 Subject: [PATCH 0116/3075] fix or remove links to wiki the wiki has been mercifully taken offline --- contribute/documentation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/documentation.md b/contribute/documentation.md index 0111c5c15d..a329f67369 100644 --- a/contribute/documentation.md +++ b/contribute/documentation.md @@ -31,7 +31,7 @@ without creating an issue, but please look to see if there is an issue already s ### The Main Scala Documentation Site -[docs.scala-lang.org](https://wiki.scala-lang.org/) houses the primary source of written, non-API documentation for Scala. It's a github project that you can fork and submit pull requests from. It includes: +[docs.scala-lang.org](https://docs.scala-lang.org/) houses the primary source of written, non-API documentation for Scala. It's a github project that you can fork and submit pull requests from. It includes: * Overviews * Tutorials From 81a9902665dd90bd0b7e4b971e9f358a2bb492ab Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Thu, 10 Aug 2017 12:29:30 -0700 Subject: [PATCH 0117/3075] scala.github.com -> docs.scala-lang --- _contribute_resources/3-code-reviews.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_contribute_resources/3-code-reviews.md b/_contribute_resources/3-code-reviews.md index 2ab235993b..ffdd6d2672 100644 --- a/_contribute_resources/3-code-reviews.md +++ b/_contribute_resources/3-code-reviews.md @@ -5,4 +5,4 @@ icon: fa fa-eye --- Review pull requests against [scala/scala](https://github.com/scala/scala/pulls), [scala/scala-lang](https://github.com/scala/scala-lang/pulls), -[scala/scala.github.com](https://github.com/scala/scala.github.com/pulls)and others. \ No newline at end of file +[scala/docs.scala-lang](https://github.com/scala/docs.scala-lang/pulls)and others. From 287b50a18d6d5cd3f07e6c9de8c7df7fe7a0da0b Mon Sep 17 00:00:00 2001 From: Jimin Hsieh Date: Thu, 17 Aug 2017 21:11:58 +0800 Subject: [PATCH 0118/3075] Fix broken links of https://scala-lang.org/contribute/#contribute. --- _contribute_resources/1-documentation.md | 4 ++-- _contribute_resources/2-bug-fixes.md | 2 +- _contribute_resources/3-code-reviews.md | 2 +- _contribute_resources/4-core-libraries.md | 4 ++-- _contribute_resources/5-ide-and-build-tools.md | 4 ++-- _contribute_resources/6-compiler-language.md | 4 ++-- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/_contribute_resources/1-documentation.md b/_contribute_resources/1-documentation.md index 0d9c198ffd..54f18c938c 100644 --- a/_contribute_resources/1-documentation.md +++ b/_contribute_resources/1-documentation.md @@ -1,6 +1,6 @@ --- title: Documentation -link: /contribute/documentation/ +link: /contribute/documentation.html icon: fa fa-file-text --- -[Scaladoc (API)](/contribute/scala-standard-library-api-documentation/), [docs.scala-lang.org](http://docs.scala-lang.org/contribute.html) and [scala-lang.org](https://github.com/scala/scala-lang). +[Scaladoc (API)](/contribute/scala-standard-library-api-documentation.html), [docs.scala-lang.org](http://docs.scala-lang.org/contribute.html) and [scala-lang.org](https://github.com/scala/scala-lang). diff --git a/_contribute_resources/2-bug-fixes.md b/_contribute_resources/2-bug-fixes.md index 8661ab9614..cca6269e06 100644 --- a/_contribute_resources/2-bug-fixes.md +++ b/_contribute_resources/2-bug-fixes.md @@ -1,6 +1,6 @@ --- title: Bug fixes -link: /contribute/guide/ +link: /contribute/guide.html icon: fa fa-pencil --- Issues with the tools, core libraries and compiler. Also you can help us by [reporting bugs](/contribute/bug-reporting-guide.html). diff --git a/_contribute_resources/3-code-reviews.md b/_contribute_resources/3-code-reviews.md index ffdd6d2672..3de87cd929 100644 --- a/_contribute_resources/3-code-reviews.md +++ b/_contribute_resources/3-code-reviews.md @@ -1,6 +1,6 @@ --- title: Code Reviews -link: /contribute/codereviews/ +link: /contribute/codereviews.html icon: fa fa-eye --- Review pull requests against [scala/scala](https://github.com/scala/scala/pulls), diff --git a/_contribute_resources/4-core-libraries.md b/_contribute_resources/4-core-libraries.md index 7ad75c5752..06f1018479 100644 --- a/_contribute_resources/4-core-libraries.md +++ b/_contribute_resources/4-core-libraries.md @@ -1,6 +1,6 @@ --- title: Core Libraries -link: /contribute/corelibs/ +link: /contribute/corelibs.html icon: fa fa-clipboard --- -Update and expand the capabilities of the core (and associated) Scala libraries. \ No newline at end of file +Update and expand the capabilities of the core (and associated) Scala libraries. diff --git a/_contribute_resources/5-ide-and-build-tools.md b/_contribute_resources/5-ide-and-build-tools.md index 4b8bd2ed52..7202f0d953 100644 --- a/_contribute_resources/5-ide-and-build-tools.md +++ b/_contribute_resources/5-ide-and-build-tools.md @@ -1,6 +1,6 @@ --- title: IDE and Build Tools -link: /contribute/tools/ +link: /contribute/tools.html icon: fa fa-terminal --- -Enhance the Scala tools with features for build tools, IDE plug-ins and other related projects. \ No newline at end of file +Enhance the Scala tools with features for build tools, IDE plug-ins and other related projects. diff --git a/_contribute_resources/6-compiler-language.md b/_contribute_resources/6-compiler-language.md index 0c4eaa1325..fcfea35d5a 100644 --- a/_contribute_resources/6-compiler-language.md +++ b/_contribute_resources/6-compiler-language.md @@ -1,6 +1,6 @@ --- title: Compiler/Language -link: /contribute/guide/#larger-changes-new-features +link: /contribute/guide.html#larger-changes-new-features icon: fa fa-gears --- -Larger language features and compiler enhancements including language specification and SIPs. \ No newline at end of file +Larger language features and compiler enhancements including language specification and SIPs. From 18f49fc7d95e020cb39e4c2130299fe5b45b41a6 Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Thu, 17 Aug 2017 17:33:08 +0200 Subject: [PATCH 0119/3075] More link fixes --- contribute/codereviews.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/codereviews.md b/contribute/codereviews.md index 2c56b4ed37..ab321fd2ca 100644 --- a/contribute/codereviews.md +++ b/contribute/codereviews.md @@ -15,7 +15,7 @@ own pull requests. ### Review Guidelines -[Code of Conduct reminder](/conduct/) +[Code of Conduct reminder]({{ site.baseurl }}/conduct.html) * Keep comments on-topic, concise and precise. * Attach comments to particular lines or regions they pertain to whenever possible. From aaf513b07215bffa7bd36d76d37922d2655a7767 Mon Sep 17 00:00:00 2001 From: Janek Bogucki Date: Wed, 6 Sep 2017 11:17:58 +0100 Subject: [PATCH 0120/3075] Extend partest guide with sbt and mention batch script removals --- contribute/partest-guide.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/contribute/partest-guide.md b/contribute/partest-guide.md index ce4f84ecf1..dccee46a1c 100644 --- a/contribute/partest-guide.md +++ b/contribute/partest-guide.md @@ -5,17 +5,37 @@ layout: inner-page-no-masthead includeTOC: true --- -Partest is a custom parallel testing tool that we use to run the test suite for the Scala compiler and library. Go the scala project folder from your local checkout and run it via `ant` or standalone as follows. +Partest is a custom parallel testing tool that we use to run the test suite for the Scala compiler and library. Go to the scala project folder from your local checkout and run it via `sbt`, `ant` or standalone as follows. + +## Using sbt + +The test suite can be run from the sbt console with: + + > partest + +You can get a summary of the usage by running `partest --help`. + +If you would like to run particular tests pass the test paths as arguments + + > partest test/files/pos/bounds.scala test/scaladoc/run/diagrams-base.scala + +To run only the Scaladoc tests use `--srcpath` with the location of the tests + + > partest --srcpath scaladoc ## Using ant +Please note support for ant was removed on the 2.12 branch. + The test suite can be run by using ant from the command line: $ ant test.suite ## Standalone -There are launch scripts `partest` and `partest.bat` in the `test` folder of the scala project. To have partest run failing tests only and print details about test failures to the console, you can use +Please note the standalone scripts mentioned below were removed in 2.12.2. sbt is the perferred way to run the test suite. + +There are launch scripts `partest` and `partest.bat` in the `test` folder of the scala project. To have partest run failing tests only and print details about test failures to the console, you can use ./test/partest --show-diff --show-log --failed From 48e43e80173efa233cb422e6e1a888c79c74a12e Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Wed, 6 Sep 2017 16:23:34 -0700 Subject: [PATCH 0121/3075] fix typo --- contribute/partest-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/partest-guide.md b/contribute/partest-guide.md index dccee46a1c..e7e10621e1 100644 --- a/contribute/partest-guide.md +++ b/contribute/partest-guide.md @@ -33,7 +33,7 @@ The test suite can be run by using ant from the command line: ## Standalone -Please note the standalone scripts mentioned below were removed in 2.12.2. sbt is the perferred way to run the test suite. +Please note the standalone scripts mentioned below were removed in 2.12.2. sbt is the preferred way to run the test suite. There are launch scripts `partest` and `partest.bat` in the `test` folder of the scala project. To have partest run failing tests only and print details about test failures to the console, you can use From 6f2ca77dae73a6b1ccbedc639c5aed31940c8107 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Wed, 15 Nov 2017 10:59:10 +0100 Subject: [PATCH 0122/3075] Fix links to Hacker guide --- contribute/guide.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/contribute/guide.md b/contribute/guide.md index a824e2297f..ae69f50fd2 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -23,7 +23,7 @@ includeTOC: true

Get cracking on some easy to approach issues.

-

Hacker's guide

+

Hacker guide

Learn to write good code and improve your chances of contributing to the Scala galaxy.

@@ -57,16 +57,16 @@ This is the impatient developer's checklist for the steps to submit a bug-fix pu 1. [Select a bug to fix from JIRA](/contribute/#community-tickets), or if you found the bug yourself and want to fix it, [create a JIRA issue](/contribute/bug-reporting-guide.html) (but please [make sure it's not a duplicate](/contribute/bug-reporting-guide.html#reporting-confirmed-bugs-is-a-sin)). 2. Optional ([but recommended](/contribute/scala-internals/#why-its-a-good-idea)), announce your intention to work on the bug on [Scala Contributors](https://contributors.scala-lang.org/). After all, don't you want to work on a team with -[these friendly people](/contribute/hacker-guide/#connect) - it's one of the perks of contributing. -3. [Fork the Scala repository](/contribute/hacker-guide/#fork) and clone your fork (if you haven't already). -4. [Create a feature branch](/contribute/hacker-guide/#branch) to work on: use the branch name `issue/NNNN` where NNNN is the JIRA issue number. -5. [Fix the bug, or implement the new small feature](/contribute/hacker-guide/#implement), include new tests (yes, for bug fixes too). -6. [Test, rinse](/contribute/hacker-guide/#test) and [test some more](/contribute/partest-guide/) until [all the tests pass](/contribute/hacker-guide/#verify). -7. [Commit your changes](/contribute/hacker-guide#commit) to your feature branch in your fork. Please choose your commit message based on the [Git Hygiene](https://github.com/scala/scala#user-content-git-hygiene) section of the Scala project README. +[these friendly people](/contribute/hacker-guide.html#1-connect) - it's one of the perks of contributing. +3. [Fork the Scala repository](/contribute/hacker-guide.html#fork) and clone your fork (if you haven't already). +4. [Create a feature branch](/contribute/hacker-guide.html#branch) to work on: use the branch name `issue/NNNN` where NNNN is the JIRA issue number. +5. [Fix the bug, or implement the new small feature](/contribute/hacker-guide.html#implement), include new tests (yes, for bug fixes too). +6. [Test, rinse](/contribute/hacker-guide.html#test) and [test some more](/contribute/partest-guide/) until [all the tests pass](/contribute/hacker-guide.html#verify). +7. [Commit your changes](/contribute/hacker-guide.html#commit) to your feature branch in your fork. Please choose your commit message based on the [Git Hygiene](https://github.com/scala/scala#user-content-git-hygiene) section of the Scala project README. 8. If necessary [re-write git history](http://git-scm.com/book/en/Git-Branching-Rebasing) so that [commits are organized by major steps to the fix/feature]( https://github.com/scala/scala#git-hygiene). For bug fixes, a single commit is requested, for features several commits may be desirable (but each separate commit must compile and pass all tests) 9. [Submit a pull request](./hacker-guide.html#submit) following the [Scala project pull-request guidelines](http://docs.scala-lang.org/scala/pull-request-policy.html). -10. [Work with a reviewer](https://github.com/scala/scala#reviewing) to [get your pull request merged in](/contribute/hacker-guide/#review). +10. [Work with a reviewer](https://github.com/scala/scala#reviewing) to [get your pull request merged in](/contribute/hacker-guide.html#review). 11. Celebrate! Need more information or a little more hand-holding for the first one? We got you covered: take a read through the entire [Hacker Guide](./hacker-guide.html) for an example of implementing a new feature (some of the steps can be skipped for bug fixes, this will be obvious from reading it, but many of the steps here will help with bug fixes too). @@ -78,4 +78,4 @@ and on the implementation plan. Announce the change on the [Scala Contributors](https://contributors.scala-lang.org/) mailing list and get developer feedback. For really complex changes, a [Scala Improvement Process (SIP)](http://docs.scala-lang.org/sips/) document might be required, but the first step is always to discuss it on the mailing list and if a SIP is required, that will be discussed on the mailing list. Contributions, big or small, simple or complex, controversial or undisputed, need to materialize as patches against -the Scala project source tree. The [hacker guide](/contribute/hacker-guide/) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. +the Scala project source tree. The [hacker guide](/contribute/hacker-guide.html) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. From 3db9bb55a2f392f80f5bdb54c7811f948ade5b33 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sat, 27 Jan 2018 21:04:51 +0100 Subject: [PATCH 0123/3075] Add missing space --- _contribute_resources/3-code-reviews.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_contribute_resources/3-code-reviews.md b/_contribute_resources/3-code-reviews.md index 3de87cd929..2fc057eb0d 100644 --- a/_contribute_resources/3-code-reviews.md +++ b/_contribute_resources/3-code-reviews.md @@ -5,4 +5,4 @@ icon: fa fa-eye --- Review pull requests against [scala/scala](https://github.com/scala/scala/pulls), [scala/scala-lang](https://github.com/scala/scala-lang/pulls), -[scala/docs.scala-lang](https://github.com/scala/docs.scala-lang/pulls)and others. +[scala/docs.scala-lang](https://github.com/scala/docs.scala-lang/pulls) and others. From 725800ebd3d4e2b71407ea2017428853ce2b96a2 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sat, 27 Jan 2018 21:11:47 +0100 Subject: [PATCH 0124/3075] Fix links --- contribute/corelibs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contribute/corelibs.md b/contribute/corelibs.md index c06a741915..aeb19e89af 100644 --- a/contribute/corelibs.md +++ b/contribute/corelibs.md @@ -8,9 +8,9 @@ includeTOC: true There are several options for contributing to Scala's core libraries. You can: -* Help with [Documentation](/contribute/scala-standard-library-api-documentation/). +* Help with [Documentation](/contribute/documentation.html). * [Report Bugs or Issues](/contribute/bug-reporting-guide.html) against the core libraries. -* [Fix Bugs or Issues](/contribute/guide/) against the +* [Fix Bugs or Issues](/contribute/guide.html) against the [reported library bugs/issues](https://issues.scala-lang.org/issues/?filter=13001). * Contribute significant new functionality or a new API by submitting a Scala Library Improvement Process (SLIP) Document. From 56abdcb1b0912957fc4e9f5c92018fbed73c04cb Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sat, 27 Jan 2018 21:12:47 +0100 Subject: [PATCH 0125/3075] Link to GitHub instead of JIRA --- contribute/corelibs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/corelibs.md b/contribute/corelibs.md index aeb19e89af..e1f10cb790 100644 --- a/contribute/corelibs.md +++ b/contribute/corelibs.md @@ -11,7 +11,7 @@ There are several options for contributing to Scala's core libraries. You can: * Help with [Documentation](/contribute/documentation.html). * [Report Bugs or Issues](/contribute/bug-reporting-guide.html) against the core libraries. * [Fix Bugs or Issues](/contribute/guide.html) against the - [reported library bugs/issues](https://issues.scala-lang.org/issues/?filter=13001). + [reported library bugs/issues](https://github.com/scala/bug). * Contribute significant new functionality or a new API by submitting a Scala Library Improvement Process (SLIP) Document. From 46fc7ea2c1117a6fc9ea612e4cf53d92f802aa5d Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sat, 27 Jan 2018 21:19:43 +0100 Subject: [PATCH 0126/3075] Reword and link to GitHub instead of JIRA --- contribute/guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/guide.md b/contribute/guide.md index ae69f50fd2..1b530a1769 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -43,7 +43,7 @@ The main Scala project consists of the standard Scala library, the Scala reflect the Scala compiler and the Scaladoc tool. This means there's plenty to choose from when deciding what to work on. Typically the scaladoc tool provides a low entry point for new committers, so it is a good first step into contributing. -On the Scala bug tracker you will find many bugs that are [marked as good starting points to contributing ("community" bugs)](https://issues.scala-lang.org/secure/IssueNavigator.jspa?requestId=12111) or [that are not currently assigned](https://issues.scala-lang.org/secure/IssueNavigator.jspa?requestId=12112) and that you could pick up. Once you decided on a ticket to look at, see the next step on how to proceed further. +On the [Scala bug tracker](https://github.com/scala/bug) you will find the bugs that you could pick up. Once you decided on a ticket to look at, see the next step on how to proceed further. If you are interested in contributing code, we ask you to sign the [Scala Contributor License Agreement](http://www.lightbend.com/contribute/cla/scala), From 381b641dfb1a00ef2da9d646078cc4e8a85e4501 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sat, 27 Jan 2018 21:20:28 +0100 Subject: [PATCH 0127/3075] Link to GitHub instead of JIRA --- contribute/scala-standard-library-api-documentation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/scala-standard-library-api-documentation.md b/contribute/scala-standard-library-api-documentation.md index c64a176cde..6467cea947 100644 --- a/contribute/scala-standard-library-api-documentation.md +++ b/contribute/scala-standard-library-api-documentation.md @@ -42,7 +42,7 @@ and identify missing, incorrect or inadequate documentation. A good place to sta package objects for important packages (these often get overlooked for documentation and are a good place for API overviews). -If you find an issue, please log it in the [Scala issue tracker](https://issues.scala-lang.org) +If you find an issue, please log it in the [Scala bug tracker](https://github.com/scala/bug) **after making sure it is not already logged as an issue**. To help with disambiguation, please use the following format for issue title: From 74ce0815244088f76cab5e1f3d9cab4e4248a59d Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sat, 27 Jan 2018 21:39:58 +0100 Subject: [PATCH 0128/3075] Fix ironically broken link --- contribute/tools.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/tools.md b/contribute/tools.md index de96e19fa5..599cbf381e 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -103,7 +103,7 @@ if you would like to help revive them. ### Broken Links? -Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](/contribute/documentation/#updating-scala-langorg) to fix it. +Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](/contribute/documentation.html#updating-scala-langorg) to fix it. ### Projects From 832e674c2c10dcf1f1341d50dbcc549e917662f6 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sat, 27 Jan 2018 21:41:15 +0100 Subject: [PATCH 0129/3075] Link to GitHub instead of JIRA --- contribute/tools.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/tools.md b/contribute/tools.md index 599cbf381e..8337c10935 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -19,7 +19,7 @@ projects: icon: https://avatars1.githubusercontent.com/u/57059?v=3&s=200 link: https://github.com/scala/scala homeLink: http://www.scala-lang.org/api - issuesLink: https://issues.scala-lang.org/issues/?jql=status%20%3D%20Open%20AND%20component%20%3D%20%22Scaladoc%20Tool%22 + issuesLink: https://github.com/scala/bug/labels/scaladoc readmeLink: https://github.com/scala/scala#welcome contributingLink: http://scala-lang.org/contribute/guide.html - title: Scala IDE From e4f39bf320ae3e8ee2fda6a3e91b94644ae239da Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sat, 27 Jan 2018 21:42:23 +0100 Subject: [PATCH 0130/3075] Fix Scalariform section --- contribute/tools.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contribute/tools.md b/contribute/tools.md index 8337c10935..feb11afa8f 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -80,8 +80,8 @@ projectsInNeed: issuesLink: https://issues.scala-lang.org/issues/?jql=status%20%3D%20Open%20AND%20text%20~%20%22scalap%22 readmeLink: https://github.com/scala/scala#welcome contributingLink: https://github.com/sbt/sbt/blob/0.13/CONTRIBUTING.md - - title: Scaladoc Tool - description: (Contribute through scala/scala) + - title: Scalariform + description: Scala source code formatter icon: /resources/img/white-line.png link: https://github.com/mdr/scalariform homeLink: https://github.com/mdr/scalariform/wiki/Command-line-tool From 4a9c5f05ca7161756ae3b7f1be520908caa53910 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sat, 27 Jan 2018 21:46:12 +0100 Subject: [PATCH 0131/3075] Remove Scalap --- contribute/tools.md | 8 -------- 1 file changed, 8 deletions(-) diff --git a/contribute/tools.md b/contribute/tools.md index feb11afa8f..a1e2ef78e2 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -72,14 +72,6 @@ projects: contributingLink: https://github.com/scala/scala-abide#extending-abide projectsInNeed: - - title: Scalap - description: Scala Decoder (part of scala/scala) - icon: https://avatars1.githubusercontent.com/u/57059?v=3&s=200 - link: https://github.com/scala/scala - homeLink: - issuesLink: https://issues.scala-lang.org/issues/?jql=status%20%3D%20Open%20AND%20text%20~%20%22scalap%22 - readmeLink: https://github.com/scala/scala#welcome - contributingLink: https://github.com/sbt/sbt/blob/0.13/CONTRIBUTING.md - title: Scalariform description: Scala source code formatter icon: /resources/img/white-line.png From 0dc0f0dab8532365fd069f7f3984d66976562635 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sat, 27 Jan 2018 21:52:55 +0100 Subject: [PATCH 0132/3075] Link to GitHub instead of JIRA --- contribute/hacker-guide.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index a10fbb70eb..4200df478c 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -17,7 +17,7 @@ Other good starting points for first-time contributors include the [Scala README Let's say that you particularly enjoy the new string interpolation language feature introduced in Scala 2.10.0, and you use it quite heavily. Though, there's an annoying issue -which you occasionally stumble upon: the formatting string interpolator `f` [does not support](https://issues.scala-lang.org/browse/SI-6725) +which you occasionally stumble upon: the formatting string interpolator `f` [does not support](https://github.com/scala/bug/issues/6725) new line tokens `%n`. One approach would be to go the mailing list, request that the bug be fixed, and then to wait indefinitely for the fix arrive. Another approach would be to instead patch Scala oneself, and to submit the fix to the Scala repository in hopes that it might make it into a subsequent release. @@ -88,10 +88,10 @@ Before you start making changes, always create your own branch. Never work on th the changes you plan on making. Use a prefix that describes the nature of your change. There are essentially two kinds of changes: bug fixes and new features. -* For bug fixes, use `issue/NNNN` or `ticket/NNNN` for bug NNNN from the [Scala issue tracker](https://issues.scala-lang.org/). +* For bug fixes, use `issue/NNNN` or `ticket/NNNN` for bug NNNN from the [Scala bug tracker](https://github.com/scala/bug). * For new feature use `topic/XXX` for feature XXX. Use feature names that make sense in the context of the whole Scala project and not just to you personally. For example, if you work on diagrams in Scaladoc, use `topic/scaladoc-diagrams` instead of just `topic/diagrams` would be a good branch name. -Since in our example, we're going to fix an existing bug [SI-6725](https://issues.scala-lang.org/browse/SI-6725), we'll create a branch named `ticket/6725`. +Since in our example, we're going to fix an existing bug [6725](https://github.com/scala/bug/issues/6725), we'll create a branch named `ticket/6725`. 16:39 ~/Projects/scala (master)$ git checkout -b ticket/6725 Switched to a new branch 'ticket/6725' @@ -108,7 +108,7 @@ You need the following tools: * `sbt`, an interactive build tool commonly used in Scala projects. Acquiring sbt manually is not necessary -- the recommended approach is to download the [sbt-extras runner script](https://github.com/paulp/sbt-extras/blob/master/sbt) and use it in place of `sbt`. The script will download and run the correct version of sbt when run from the Scala repository's root directory. * `curl` -- the build uses `curl` in the `pull-binary-libs.sh` script to download bootstrap libs. -OS X and Linux builds should work. Windows is supported, but it might have issues. Please report to [the issue tracker](https://issues.scala-lang.org/) if you encounter any. +OS X and Linux builds should work. Windows is supported, but it might have issues. Please report to the [Scala bug tracker](https://github.com/scala/bug) if you encounter any. Building Scala is as easy as running `sbt dist/mkPack` in the root of your cloned repository. In general, it's much more efficient to enter the `sbt` shell once and run the various tasks from there, instead of running each task by launching `sbt some-task` on your command prompt. @@ -136,7 +136,7 @@ Typically you would want to first make sure that your changes work on a small ex by running a comprehensive test suite. We'll start by creating a `sandbox` directory (`./sandbox` is listed in the .gitignore of the Scala repository), which will hold a single test file and its compilation results. First, let's make sure that -[the bug](https://issues.scala-lang.org/browse/SI-6725) is indeed reproducible by putting together a simple test and compiling and running it with the Scala compiler that we built using `sbt`. The Scala compiler that we just built is located in `build/pack/bin`. +[the bug](https://github.com/scala/bug/issues/6725) is indeed reproducible by putting together a simple test and compiling and running it with the Scala compiler that we built using `sbt`. The Scala compiler that we just built is located in `build/pack/bin`. 17:25 ~/Projects/scala (ticket/6725)$ mkdir sandbox 17:26 ~/Projects/scala (ticket/6725)$ cd sandbox @@ -221,7 +221,7 @@ Tools like Scaladoc also welcome contributions. Unfortunately these smaller proj ### Interlude -To fix [the bug we're interested in](https://issues.scala-lang.org/browse/SI-6725) we've tracked the `StringContext.f` interpolator +To fix [the bug we're interested in](https://github.com/scala/bug/issues/6725) we've tracked the `StringContext.f` interpolator down to a macro implemented in `MacroImplementations.scala` There we notice that the interpolator only processes conversions, but not tokens like `%n`. Looks like an easy fix. From 5ad09fd1367de5fc65748ded6df8c003c636ee84 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sun, 28 Jan 2018 00:11:41 +0100 Subject: [PATCH 0133/3075] Remove link to 'Actors Migration Kit' --- contribute/bug-reporting-guide.md | 1 - 1 file changed, 1 deletion(-) diff --git a/contribute/bug-reporting-guide.md b/contribute/bug-reporting-guide.md index 05569ff8e4..71cb5e7ad8 100644 --- a/contribute/bug-reporting-guide.md +++ b/contribute/bug-reporting-guide.md @@ -21,7 +21,6 @@ If your issue is related to any of the following external projects, make sure to - [Akka](http://doc.akka.io/docs/akka/current/project/issue-tracking.html) - [Play!](http://github.com/playframework/Play20/issues) - [Slick](http://github.com/slick/slick/issues) - - [Actors Migration Kit](http://github.com/scala/actors-migration/issues?state=open) - [Scala IDE](https://scala-ide-portfolio.assembla.com/spaces/scala-ide/support/tickets) - [sbt](https://github.com/sbt/sbt/issues) From 1b4d548cbcfe92a861d226c07164006e8afb44fe Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sun, 28 Jan 2018 00:16:53 +0100 Subject: [PATCH 0134/3075] Replace references to 'JIRA' with 'GitHub' --- contribute/guide.md | 4 ++-- contribute/scala-standard-library-api-documentation.md | 6 +++--- contribute/tools.md | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contribute/guide.md b/contribute/guide.md index 1b530a1769..c2949683ae 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -54,12 +54,12 @@ unencumbered by copyrights or patents. This is the impatient developer's checklist for the steps to submit a bug-fix pull request to the Scala project. For more information, description and justification for the steps, follow the links in that step. Further specific instructions for the release of Scala you are targeting can be found in the `CONTRIBUTING.md` file for that [github branch](https://github.com/scala/scala) -1. [Select a bug to fix from JIRA](/contribute/#community-tickets), or if you found the bug yourself and want to fix it, [create a JIRA issue](/contribute/bug-reporting-guide.html) (but please +1. [Select a bug to fix from GitHub](/contribute/#community-tickets), or if you found the bug yourself and want to fix it, [create a GitHub issue](/contribute/bug-reporting-guide.html) (but please [make sure it's not a duplicate](/contribute/bug-reporting-guide.html#reporting-confirmed-bugs-is-a-sin)). 2. Optional ([but recommended](/contribute/scala-internals/#why-its-a-good-idea)), announce your intention to work on the bug on [Scala Contributors](https://contributors.scala-lang.org/). After all, don't you want to work on a team with [these friendly people](/contribute/hacker-guide.html#1-connect) - it's one of the perks of contributing. 3. [Fork the Scala repository](/contribute/hacker-guide.html#fork) and clone your fork (if you haven't already). -4. [Create a feature branch](/contribute/hacker-guide.html#branch) to work on: use the branch name `issue/NNNN` where NNNN is the JIRA issue number. +4. [Create a feature branch](/contribute/hacker-guide.html#branch) to work on: use the branch name `issue/NNNN` where NNNN is the GitHub issue number. 5. [Fix the bug, or implement the new small feature](/contribute/hacker-guide.html#implement), include new tests (yes, for bug fixes too). 6. [Test, rinse](/contribute/hacker-guide.html#test) and [test some more](/contribute/partest-guide/) until [all the tests pass](/contribute/hacker-guide.html#verify). 7. [Commit your changes](/contribute/hacker-guide.html#commit) to your feature branch in your fork. Please choose your commit message based on the [Git Hygiene](https://github.com/scala/scala#user-content-git-hygiene) section of the Scala project README. diff --git a/contribute/scala-standard-library-api-documentation.md b/contribute/scala-standard-library-api-documentation.md index 6467cea947..cae67a5db0 100644 --- a/contribute/scala-standard-library-api-documentation.md +++ b/contribute/scala-standard-library-api-documentation.md @@ -22,7 +22,7 @@ contribution steps and guidelines. Thank you.* Since API documentation is located in Scala source code files, the process for contributing API documentation is similar to that of contributing bug-fixes -to the Scala code base, but without the requirement that there be an issue filed on JIRA +to the Scala code base, but without the requirement that there be an issue filed on GitHub first. When forking/branching, just use a `scaladoc/xxxx` branch name, where xxxx is a descriptive, but short branch name (e.g. `scaladoc/future-object`). However, if an issue *does* exist, please use `issue/NNNN`, where NNNN is the ticket number, @@ -78,9 +78,9 @@ Please familiarize yourself with the following before contributing new API documentation to save time, effort, mistakes and repetition. * [Forking the Repo](./hacker-guide.html#set-up) - follow the setup steps through - the Branch section. If providing new documentation related to an existing JIRA issue, use `issue/NNNN` + the Branch section. If providing new documentation related to an existing GitHub issue, use `issue/NNNN` or `ticket/NNNN` as the guide states. If providing API documentation with no associated - JIRA issue, use `scaladoc/xxxx` instead. + GitHub issue, use `scaladoc/xxxx` instead. * [Scaladoc for library authors](http://docs.scala-lang.org/overviews/scaladoc/for-library-authors.html) covers the use of scaladoc tags, markdown and other features. * [Scaladoc's interface](http://docs.scala-lang.org/overviews/scaladoc/interface.html) diff --git a/contribute/tools.md b/contribute/tools.md index a1e2ef78e2..19f953785f 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -86,7 +86,7 @@ The links below are to a number of Scala build and IDE related projects that are Since these tools are in separate projects, they may (and likely will) have their own rules and guidelines for contributing. The [Hacker Guide](/contribute/hacker-guide/) and [Bug-fixing](/contribute/guide/) pages will likely have much in the way of related information on how to contribute to these projects, and are recommended reading. You should also check the README.md and (if it's present) CONTRIBUTING.md files from the actual projects before contributing to them. -Typically, issues for these projects will be reported and kept in the github project issue tracker for that project rather than in the Scala project JIRA. +Typically, issues for these projects will be reported and kept in the GitHub project issue tracker for that project rather than in the Scala bug tracker. Many of these projects have a gitter channel (usually listed in the README or CONTRIBUTING documents) which is a great place to discuss proposed work before commencing. There are some projects in this section that are in From 76665323a75257fc23570b416e1dd102824b5e1d Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sun, 28 Jan 2018 00:30:03 +0100 Subject: [PATCH 0135/3075] Remove 'Community Tickets' section almost completely --- contribute/index.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/contribute/index.md b/contribute/index.md index f56a91c163..f8d71a1f69 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -29,10 +29,8 @@ Coordination of contribution efforts takes place on ### Community Tickets -The following links provide starting points for -various contributor activities: - -{% include column-list-of-items.html collection=site.contribute_community_tickets %} +All issues can be found in the [Scala bug tracker](https://github.com/scala/bug). Most issues are labeled +to make it easier to find issues you are interested in. ### Tools and Libraries From 0dda54719465b83ce5267a663ca5e31927c51486 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sun, 28 Jan 2018 11:48:36 +0100 Subject: [PATCH 0136/3075] Fix links to Mailing Lists --- contribute/hacker-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index a10fbb70eb..c6ce1c7eea 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -30,7 +30,7 @@ Sometimes it's appealing to hack alone and not to have to interact with others o this might not be the very best idea. There are people in the Scala community who have spent years accumulating knowledge about Scala libraries and internals. They might provide unique insights and, what's even better, direct assistance in their areas, so it is not only advantageous, but recommended to communicate with the community about your new patch. -Typically bug fixes and new features start out as an idea or an experiment posted on one of [our mailing lists]({{ site.baseurl }}/community/index.html#mailing-lists) to find out how people feel +Typically bug fixes and new features start out as an idea or an experiment posted on one of [our mailing lists]({{ site.baseurl }}/community/index.html#forums--mailing-lists) to find out how people feel about things you want to implement. People proficient in certain areas of Scala usually monitor mailing lists, so you'll often get some help by simply posting a message. But the most efficient way to connect is to cc your message to one of the people responsible for maintaining the aspect of Scala which you wish to contribute to. From 2f7d9fbed9fbb41c9489d5cb22c148e4f16155d1 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sun, 28 Jan 2018 12:43:49 +0100 Subject: [PATCH 0137/3075] Fix broken links --- contribute/codereviews.md | 4 ++-- contribute/guide.md | 2 +- contribute/scala-standard-library-api-documentation.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contribute/codereviews.md b/contribute/codereviews.md index ab321fd2ca..6e0a2592b6 100644 --- a/contribute/codereviews.md +++ b/contribute/codereviews.md @@ -6,7 +6,7 @@ includeTOC: true --- ## Code Review Contributions -In addition to [bug fixing](/contribute/guide/), you can help us review +In addition to [bug fixing](/contribute/guide.html), you can help us review [waiting pull requests](#pull-requests-awaiting-comment). This is also a good (and recommended) way to get to know the feel of the bug-fixing and submissions process before jumping in with your @@ -51,4 +51,4 @@ own pull requests.
-Also note that the [Tools contributions](/contribute/tools/) page has more projects that will generate pull requests. +Also note that the [Tools contributions](/contribute/tools.html) page has more projects that will generate pull requests. diff --git a/contribute/guide.md b/contribute/guide.md index ae69f50fd2..1f1a014a1b 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -61,7 +61,7 @@ This is the impatient developer's checklist for the steps to submit a bug-fix pu 3. [Fork the Scala repository](/contribute/hacker-guide.html#fork) and clone your fork (if you haven't already). 4. [Create a feature branch](/contribute/hacker-guide.html#branch) to work on: use the branch name `issue/NNNN` where NNNN is the JIRA issue number. 5. [Fix the bug, or implement the new small feature](/contribute/hacker-guide.html#implement), include new tests (yes, for bug fixes too). -6. [Test, rinse](/contribute/hacker-guide.html#test) and [test some more](/contribute/partest-guide/) until [all the tests pass](/contribute/hacker-guide.html#verify). +6. [Test, rinse](/contribute/hacker-guide.html#test) and [test some more](/contribute/partest-guide.html) until [all the tests pass](/contribute/hacker-guide.html#verify). 7. [Commit your changes](/contribute/hacker-guide.html#commit) to your feature branch in your fork. Please choose your commit message based on the [Git Hygiene](https://github.com/scala/scala#user-content-git-hygiene) section of the Scala project README. 8. If necessary [re-write git history](http://git-scm.com/book/en/Git-Branching-Rebasing) so that [commits are organized by major steps to the fix/feature]( https://github.com/scala/scala#git-hygiene). For bug fixes, a single commit is requested, for features several commits may be desirable (but each separate commit must compile and pass all tests) diff --git a/contribute/scala-standard-library-api-documentation.md b/contribute/scala-standard-library-api-documentation.md index c64a176cde..d7c69ef099 100644 --- a/contribute/scala-standard-library-api-documentation.md +++ b/contribute/scala-standard-library-api-documentation.md @@ -77,7 +77,7 @@ component so that they show up in the correct issue filters. Please familiarize yourself with the following before contributing new API documentation to save time, effort, mistakes and repetition. -* [Forking the Repo](./hacker-guide.html#set-up) - follow the setup steps through +* [Forking the Repo](./hacker-guide.html#2-set-up) - follow the setup steps through the Branch section. If providing new documentation related to an existing JIRA issue, use `issue/NNNN` or `ticket/NNNN` as the guide states. If providing API documentation with no associated JIRA issue, use `scaladoc/xxxx` instead. From f00b6f35c233152a7d5d3abea317d45369779a96 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sun, 28 Jan 2018 13:26:28 +0100 Subject: [PATCH 0138/3075] Update links for ENSIME --- contribute/tools.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contribute/tools.md b/contribute/tools.md index de96e19fa5..99bc353663 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -52,8 +52,8 @@ projects: link: https://github.com/ensime/ensime-server homeLink: http://ensime.github.io/ issuesLink: https://github.com/ensime/ensime-server/issues - readmeLink: https://github.com/ensime/ensime-server/blob/2.0/README.md - contributingLink: https://ensime.github.io/contributing/ + readmeLink: http://ensime.github.io/ + contributingLink: http://ensime.github.io/server/contributing/ - title: Scoverage description: Scala code coverage tool icon: https://avatars1.githubusercontent.com/u/5998302?v=3&s=200 From 5d99628ed6021cadecb44b96154134f4b3196795 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sun, 28 Jan 2018 16:26:24 +0100 Subject: [PATCH 0139/3075] Remove link to not-existing page --- contribute/guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/guide.md b/contribute/guide.md index 1f1a014a1b..73b21ec22b 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -65,7 +65,7 @@ This is the impatient developer's checklist for the steps to submit a bug-fix pu 7. [Commit your changes](/contribute/hacker-guide.html#commit) to your feature branch in your fork. Please choose your commit message based on the [Git Hygiene](https://github.com/scala/scala#user-content-git-hygiene) section of the Scala project README. 8. If necessary [re-write git history](http://git-scm.com/book/en/Git-Branching-Rebasing) so that [commits are organized by major steps to the fix/feature]( https://github.com/scala/scala#git-hygiene). For bug fixes, a single commit is requested, for features several commits may be desirable (but each separate commit must compile and pass all tests) -9. [Submit a pull request](./hacker-guide.html#submit) following the [Scala project pull-request guidelines](http://docs.scala-lang.org/scala/pull-request-policy.html). +9. [Submit a pull request](./hacker-guide.html#submit). 10. [Work with a reviewer](https://github.com/scala/scala#reviewing) to [get your pull request merged in](/contribute/hacker-guide.html#review). 11. Celebrate! From d13b13bd0cb4d050f5bada2b510d12b4b326701b Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Sun, 28 Jan 2018 17:42:37 +0100 Subject: [PATCH 0140/3075] Update DBuild links --- contribute/tools.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contribute/tools.md b/contribute/tools.md index 99bc353663..571005612a 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -33,11 +33,11 @@ projects: - title: DBuild description: Multi-project build tool. icon: https://avatars3.githubusercontent.com/u/784923?v=3&s=200 - link: https://github.com/typesafehub/dbuild - homeLink: http://typesafehub.github.io/dbuild - issuesLink: https://github.com/typesafehub/dbuild/issues - readmeLink: https://github.com/typesafehub/dbuild/blob/master/README.md - contributingLink: https://github.com/typesafehub/dbuild/blob/master/README.md#get-involved + link: https://github.com/lightbend/dbuild + homeLink: http://lightbend.github.io/dbuild + issuesLink: https://github.com/lightbend/dbuild/issues + readmeLink: https://github.com/lightbend/dbuild/blob/master/README.md + contributingLink: https://github.com/lightbend/dbuild/blob/master/README.md#get-involved - title: Partest description: Scala Compiler/Library Testing icon: https://avatars1.githubusercontent.com/u/57059?v=3&s=200 From df0a9ab333fd0fa892f7ccf6e28fe28cc68a7f72 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Wed, 14 Feb 2018 20:24:48 +0100 Subject: [PATCH 0141/3075] Update broken/outdated links --- contribute/tools.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contribute/tools.md b/contribute/tools.md index 4ae371d64e..0a3bd6e80e 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -44,7 +44,7 @@ projects: link: https://github.com/scala/scala-partest homeLink: http://docs.scala-lang.org/tutorials/partest-guide.html issuesLink: https://github.com/scala/scala-partest/issues - readmeLink: https://github.com/scala/scala-partest/blob/master/README.md + readmeLink: https://github.com/scala/scala-partest/blob/1.1.x/README.md contributingLink: - title: Ensime description: Scala Support for Text Editors @@ -84,7 +84,7 @@ projectsInNeed: The links below are to a number of Scala build and IDE related projects that are important in the larger Scala space, and which welcome contributions. -Since these tools are in separate projects, they may (and likely will) have their own rules and guidelines for contributing. The [Hacker Guide](/contribute/hacker-guide/) and [Bug-fixing](/contribute/guide/) pages will likely have much in the way of related information on how to contribute to these projects, and are recommended reading. You should also check the README.md and (if it's present) CONTRIBUTING.md files from the actual projects before contributing to them. +Since these tools are in separate projects, they may (and likely will) have their own rules and guidelines for contributing. The [Hacker Guide](/contribute/hacker-guide.html) and [Bug-fixing](/contribute/guide.html) pages will likely have much in the way of related information on how to contribute to these projects, and are recommended reading. You should also check the README.md and (if it's present) CONTRIBUTING.md files from the actual projects before contributing to them. Typically, issues for these projects will be reported and kept in the GitHub project issue tracker for that project rather than in the Scala bug tracker. Many of these projects have a gitter channel (usually listed in the README or CONTRIBUTING documents) which is a great place to discuss proposed work before commencing. From d0fc35c74940a14777bf68d393159ebfe56e1ed0 Mon Sep 17 00:00:00 2001 From: Olivier Blanvillain Date: Fri, 16 Feb 2018 10:59:33 +0100 Subject: [PATCH 0142/3075] s/username/user-name/ to please htmlproofer --- contribute/hacker-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index d63ad12cf4..78af87bbcd 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -67,7 +67,7 @@ If you're new to Git, don't be afraid of messing up-- there is no way you can co ### Clone -If everything went okay, you will be redirected to your own fork at `https://github.com/username/scala`, where `username` +If everything went okay, you will be redirected to your own fork at `https://github.com/user-name/scala`, where `username` is your github user name. You might find it helpful to read [http://help.github.com/fork-a-repo/](http://help.github.com/fork-a-repo/), which covers some of the things that will follow below. Then, _clone_ your repository (i.e. pull a copy from GitHub to your local machine) by running the following on the command line: From 084649625b4db03be95dcceef418f470bedaabff Mon Sep 17 00:00:00 2001 From: Olivier Blanvillain Date: Fri, 16 Feb 2018 12:00:21 +0100 Subject: [PATCH 0143/3075] Fix contribute link --- contribute/documentation.md | 6 +++--- contribute/scala-standard-library-api-documentation.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/contribute/documentation.md b/contribute/documentation.md index a329f67369..40f7ad9c6e 100644 --- a/contribute/documentation.md +++ b/contribute/documentation.md @@ -22,11 +22,11 @@ Thanks The Scala API documentation lives with the scala project source code. There are many ways you can help with improving Scaladoc, including: -* [Log issues for missing scaladoc documentation](/contribute/scala-standard-library-api-documentation/#contribute-api-documentation-bug-reports) - +* [Log issues for missing scaladoc documentation](/contribute/scala-standard-library-api-documentation.html#contribute-api-documentation-bug-reports) - Please *follow the issue submission process closely* to help prevent duplicate issues being created. -* [Claim Scaladoc Issues and Provide Documentation](/contribute/scala-standard-library-api-documentation/) - please claim issues prior to working on a specific scaladoc task to prevent duplication of effort. If you sit on an issue for too long without submitting a pull request, it will revert back to unassigned and you will need to re-claim it. +* [Claim Scaladoc Issues and Provide Documentation](/contribute/scala-standard-library-api-documentation.html) - please claim issues prior to working on a specific scaladoc task to prevent duplication of effort. If you sit on an issue for too long without submitting a pull request, it will revert back to unassigned and you will need to re-claim it. * You can also just -[submit new Scaladoc](/contribute/scala-standard-library-api-documentation/) +[submit new Scaladoc](/contribute/scala-standard-library-api-documentation.html) without creating an issue, but please look to see if there is an issue already submitted for your task and claim it if there is. If not, please post your intention to work on a specific scaladoc task on [Scala Contributors](https://contributors.scala-lang.org/) so that people know what you are doing. ### The Main Scala Documentation Site diff --git a/contribute/scala-standard-library-api-documentation.md b/contribute/scala-standard-library-api-documentation.md index f05df8663b..33ee4ad558 100644 --- a/contribute/scala-standard-library-api-documentation.md +++ b/contribute/scala-standard-library-api-documentation.md @@ -1,7 +1,7 @@ --- title: Contribute to API Documentation layout: inner-page-no-masthead -# permalink: /contribute/scala-standard-library-api-documentation/ +# permalink: /contribute/scala-standard-library-api-documentation.html includeTOC: true --- From ddd3d65b225ec930238e2dbd245b397b52a78006 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Mon, 9 Jul 2018 14:29:27 -0700 Subject: [PATCH 0144/3075] tiny formatting fix --- _overviews/plugins/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/plugins/index.md b/_overviews/plugins/index.md index 16a44644ba..3b11e43164 100644 --- a/_overviews/plugins/index.md +++ b/_overviews/plugins/index.md @@ -5,7 +5,7 @@ title: Scala Compiler Plugins discourse: true --- -**Lex Spoon (2008)** +**Lex Spoon (2008)** **Seth Tisue (2018)** ## Introduction From 0b0edeec96045239414999ab7bd1cb362c85e49a Mon Sep 17 00:00:00 2001 From: Roman Filonenko Date: Thu, 12 Jul 2018 14:35:06 +0200 Subject: [PATCH 0145/3075] add implicit keyword to the Modifiers section #1075 --- _style/declarations.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_style/declarations.md b/_style/declarations.md index f039b56595..ca6c389d5c 100644 --- a/_style/declarations.md +++ b/_style/declarations.md @@ -116,8 +116,9 @@ applicable): 1. Annotations, *each on their own line* 2. Override modifier (`override`) 3. Access modifier (`protected`, `private`) -4. Final modifier (`final`) -5. `def` +4. Implicit modifier (`implicit`) +5. Final modifier (`final`) +6. `def` From 163b725ce841fa624d1b697d14ad33e6c47c210b Mon Sep 17 00:00:00 2001 From: Jatin Gupta Date: Sun, 15 Jul 2018 22:35:34 -0700 Subject: [PATCH 0146/3075] Update documentation since deprecation now takes two arguments --- _tour/annotations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_tour/annotations.md b/_tour/annotations.md index 32220d90a6..f88ba840cc 100644 --- a/_tour/annotations.md +++ b/_tour/annotations.md @@ -16,7 +16,7 @@ redirect_from: "/tutorials/tour/annotations.html" Annotations associate meta-information with definitions. For example, the annotation `@deprecated` before a method causes the compiler to print a warning if the method is used. ``` object DeprecationDemo extends App { - @deprecated + @deprecated("deprecation message e.g. - this method will be removed", "next release in which method will be deprecated e.g. ExampleLib 2.0") def hello = "hola" hello From 0e3e8669c6e9612bd849a07c6ed5193c7acb39dc Mon Sep 17 00:00:00 2001 From: Jatin Gupta Date: Mon, 16 Jul 2018 10:20:21 -0700 Subject: [PATCH 0147/3075] Keep character count under 60 --- _tour/annotations.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_tour/annotations.md b/_tour/annotations.md index f88ba840cc..b486d7b806 100644 --- a/_tour/annotations.md +++ b/_tour/annotations.md @@ -16,7 +16,7 @@ redirect_from: "/tutorials/tour/annotations.html" Annotations associate meta-information with definitions. For example, the annotation `@deprecated` before a method causes the compiler to print a warning if the method is used. ``` object DeprecationDemo extends App { - @deprecated("deprecation message e.g. - this method will be removed", "next release in which method will be deprecated e.g. ExampleLib 2.0") + @deprecated("deprecation message", "release # which deprecates method") def hello = "hola" hello From 5a6710b8a56b85ccf7b6e95e054dfbe1ec988fd8 Mon Sep 17 00:00:00 2001 From: Philippus Date: Wed, 18 Jul 2018 18:48:21 +0200 Subject: [PATCH 0148/3075] Use jQuery from CDN, fall back to local if needed, closes #1074 --- _includes/footer.html | 3 ++- scripts/jquery-3.1.1.min.js | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 scripts/jquery-3.1.1.min.js diff --git a/_includes/footer.html b/_includes/footer.html index 7171b3c1f5..6fba4fd292 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -21,7 +21,8 @@ - + + diff --git a/scripts/jquery-3.1.1.min.js b/scripts/jquery-3.1.1.min.js new file mode 100644 index 0000000000..4c5be4c0fb --- /dev/null +++ b/scripts/jquery-3.1.1.min.js @@ -0,0 +1,4 @@ +/*! jQuery v3.1.1 | (c) jQuery Foundation | jquery.org/license */ +!function(a,b){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){"use strict";var c=[],d=a.document,e=Object.getPrototypeOf,f=c.slice,g=c.concat,h=c.push,i=c.indexOf,j={},k=j.toString,l=j.hasOwnProperty,m=l.toString,n=m.call(Object),o={};function p(a,b){b=b||d;var c=b.createElement("script");c.text=a,b.head.appendChild(c).parentNode.removeChild(c)}var q="3.1.1",r=function(a,b){return new r.fn.init(a,b)},s=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,t=/^-ms-/,u=/-([a-z])/g,v=function(a,b){return b.toUpperCase()};r.fn=r.prototype={jquery:q,constructor:r,length:0,toArray:function(){return f.call(this)},get:function(a){return null==a?f.call(this):a<0?this[a+this.length]:this[a]},pushStack:function(a){var b=r.merge(this.constructor(),a);return b.prevObject=this,b},each:function(a){return r.each(this,a)},map:function(a){return this.pushStack(r.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(f.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(a<0?b:0);return this.pushStack(c>=0&&c0&&b-1 in a)}var x=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C={}.hasOwnProperty,D=[],E=D.pop,F=D.push,G=D.push,H=D.slice,I=function(a,b){for(var c=0,d=a.length;c+~]|"+K+")"+K+"*"),S=new RegExp("="+K+"*([^\\]'\"]*?)"+K+"*\\]","g"),T=new RegExp(N),U=new RegExp("^"+L+"$"),V={ID:new RegExp("^#("+L+")"),CLASS:new RegExp("^\\.("+L+")"),TAG:new RegExp("^("+L+"|[*])"),ATTR:new RegExp("^"+M),PSEUDO:new RegExp("^"+N),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+K+"*(even|odd|(([+-]|)(\\d*)n|)"+K+"*(?:([+-]|)"+K+"*(\\d+)|))"+K+"*\\)|)","i"),bool:new RegExp("^(?:"+J+")$","i"),needsContext:new RegExp("^"+K+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+K+"*((?:-\\d)?\\d*)"+K+"*\\)|)(?=[^-]|$)","i")},W=/^(?:input|select|textarea|button)$/i,X=/^h\d$/i,Y=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,$=/[+~]/,_=new RegExp("\\\\([\\da-f]{1,6}"+K+"?|("+K+")|.)","ig"),aa=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:d<0?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ba=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ca=function(a,b){return b?"\0"===a?"\ufffd":a.slice(0,-1)+"\\"+a.charCodeAt(a.length-1).toString(16)+" ":"\\"+a},da=function(){m()},ea=ta(function(a){return a.disabled===!0&&("form"in a||"label"in a)},{dir:"parentNode",next:"legend"});try{G.apply(D=H.call(v.childNodes),v.childNodes),D[v.childNodes.length].nodeType}catch(fa){G={apply:D.length?function(a,b){F.apply(a,H.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s=b&&b.ownerDocument,w=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==w&&9!==w&&11!==w)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==w&&(l=Z.exec(a)))if(f=l[1]){if(9===w){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(s&&(j=s.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(l[2])return G.apply(d,b.getElementsByTagName(a)),d;if((f=l[3])&&c.getElementsByClassName&&b.getElementsByClassName)return G.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==w)s=b,r=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(ba,ca):b.setAttribute("id",k=u),o=g(a),h=o.length;while(h--)o[h]="#"+k+" "+sa(o[h]);r=o.join(","),s=$.test(a)&&qa(b.parentNode)||b}if(r)try{return G.apply(d,s.querySelectorAll(r)),d}catch(x){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(P,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("fieldset");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&a.sourceIndex-b.sourceIndex;if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return function(b){return"form"in b?b.parentNode&&b.disabled===!1?"label"in b?"label"in b.parentNode?b.parentNode.disabled===a:b.disabled===a:b.isDisabled===a||b.isDisabled!==!a&&ea(b)===a:b.disabled===a:"label"in b&&b.disabled===a}}function pa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function qa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return!!b&&"HTML"!==b.nodeName},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),v!==n&&(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Y.test(n.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){return a.getAttribute("id")===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}}):(d.filter.ID=function(a){var b=a.replace(_,aa);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}},d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c,d,e,f=b.getElementById(a);if(f){if(c=f.getAttributeNode("id"),c&&c.value===a)return[f];e=b.getElementsByName(a),d=0;while(f=e[d++])if(c=f.getAttributeNode("id"),c&&c.value===a)return[f]}return[]}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){if("undefined"!=typeof b.getElementsByClassName&&p)return b.getElementsByClassName(a)},r=[],q=[],(c.qsa=Y.test(n.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+K+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+K+"*(?:value|"+J+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){a.innerHTML="";var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+K+"*[*^$|!~]?="),2!==a.querySelectorAll(":enabled").length&&q.push(":enabled",":disabled"),o.appendChild(a).disabled=!0,2!==a.querySelectorAll(":disabled").length&&q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Y.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"*"),s.call(a,"[s!='']:x"),r.push("!=",N)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Y.test(o.compareDocumentPosition),t=b||Y.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?I(k,a)-I(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?I(k,a)-I(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?la(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(S,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&C.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.escape=function(a){return(a+"").replace(ba,ca)},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(_,aa),a[3]=(a[3]||a[4]||a[5]||"").replace(_,aa),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return V.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&T.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(_,aa).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+K+")"+a+"("+K+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:!b||(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(O," ")+" ").indexOf(c)>-1:"|="===b&&(e===c||e.slice(0,c.length+1)===c+"-"))}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=I(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(P,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(_,aa),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return U.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(_,aa).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:oa(!1),disabled:oa(!0),checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return X.test(a.nodeName)},input:function(a){return W.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:pa(function(){return[0]}),last:pa(function(a,b){return[b-1]}),eq:pa(function(a,b,c){return[c<0?c+b:c]}),even:pa(function(a,b){for(var c=0;c=0;)a.push(d);return a}),gt:pa(function(a,b,c){for(var d=c<0?c+b:c;++d1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function va(a,b,c){for(var d=0,e=b.length;d-1&&(f[j]=!(g[j]=l))}}else r=wa(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):G.apply(g,r)})}function ya(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ta(function(a){return a===b},h,!0),l=ta(function(a){return I(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];i1&&ua(m),i>1&&sa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(P,"$1"),c,i0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=E.call(i));u=wa(u)}G.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&ga.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=ya(b[c]),f[u]?d.push(f):e.push(f);f=A(a,za(e,d)),f.selector=a}return f},i=ga.select=function(a,b,c,e){var f,i,j,k,l,m="function"==typeof a&&a,n=!e&&g(a=m.selector||a);if(c=c||[],1===n.length){if(i=n[0]=n[0].slice(0),i.length>2&&"ID"===(j=i[0]).type&&9===b.nodeType&&p&&d.relative[i[1].type]){if(b=(d.find.ID(j.matches[0].replace(_,aa),b)||[])[0],!b)return c;m&&(b=b.parentNode),a=a.slice(i.shift().value.length)}f=V.needsContext.test(a)?0:i.length;while(f--){if(j=i[f],d.relative[k=j.type])break;if((l=d.find[k])&&(e=l(j.matches[0].replace(_,aa),$.test(i[0].type)&&qa(b.parentNode)||b))){if(i.splice(f,1),a=e.length&&sa(i),!a)return G.apply(c,e),c;break}}}return(m||h(a,n))(e,b,!p,c,!b||$.test(a)&&qa(b.parentNode)||b),c},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("fieldset"))}),ja(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){if(!c)return a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){if(!c&&"input"===a.nodeName.toLowerCase())return a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(J,function(a,b,c){var d;if(!c)return a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);r.find=x,r.expr=x.selectors,r.expr[":"]=r.expr.pseudos,r.uniqueSort=r.unique=x.uniqueSort,r.text=x.getText,r.isXMLDoc=x.isXML,r.contains=x.contains,r.escapeSelector=x.escape;var y=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&r(a).is(c))break;d.push(a)}return d},z=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},A=r.expr.match.needsContext,B=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i,C=/^.[^:#\[\.,]*$/;function D(a,b,c){return r.isFunction(b)?r.grep(a,function(a,d){return!!b.call(a,d,a)!==c}):b.nodeType?r.grep(a,function(a){return a===b!==c}):"string"!=typeof b?r.grep(a,function(a){return i.call(b,a)>-1!==c}):C.test(b)?r.filter(b,a,c):(b=r.filter(b,a),r.grep(a,function(a){return i.call(b,a)>-1!==c&&1===a.nodeType}))}r.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?r.find.matchesSelector(d,a)?[d]:[]:r.find.matches(a,r.grep(b,function(a){return 1===a.nodeType}))},r.fn.extend({find:function(a){var b,c,d=this.length,e=this;if("string"!=typeof a)return this.pushStack(r(a).filter(function(){for(b=0;b1?r.uniqueSort(c):c},filter:function(a){return this.pushStack(D(this,a||[],!1))},not:function(a){return this.pushStack(D(this,a||[],!0))},is:function(a){return!!D(this,"string"==typeof a&&A.test(a)?r(a):a||[],!1).length}});var E,F=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,G=r.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||E,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:F.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof r?b[0]:b,r.merge(this,r.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),B.test(e[1])&&r.isPlainObject(b))for(e in b)r.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&(this[0]=f,this.length=1),this}return a.nodeType?(this[0]=a,this.length=1,this):r.isFunction(a)?void 0!==c.ready?c.ready(a):a(r):r.makeArray(a,this)};G.prototype=r.fn,E=r(d);var H=/^(?:parents|prev(?:Until|All))/,I={children:!0,contents:!0,next:!0,prev:!0};r.fn.extend({has:function(a){var b=r(a,this),c=b.length;return this.filter(function(){for(var a=0;a-1:1===c.nodeType&&r.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?r.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?i.call(r(a),this[0]):i.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(r.uniqueSort(r.merge(this.get(),r(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function J(a,b){while((a=a[b])&&1!==a.nodeType);return a}r.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return y(a,"parentNode")},parentsUntil:function(a,b,c){return y(a,"parentNode",c)},next:function(a){return J(a,"nextSibling")},prev:function(a){return J(a,"previousSibling")},nextAll:function(a){return y(a,"nextSibling")},prevAll:function(a){return y(a,"previousSibling")},nextUntil:function(a,b,c){return y(a,"nextSibling",c)},prevUntil:function(a,b,c){return y(a,"previousSibling",c)},siblings:function(a){return z((a.parentNode||{}).firstChild,a)},children:function(a){return z(a.firstChild)},contents:function(a){return a.contentDocument||r.merge([],a.childNodes)}},function(a,b){r.fn[a]=function(c,d){var e=r.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=r.filter(d,e)),this.length>1&&(I[a]||r.uniqueSort(e),H.test(a)&&e.reverse()),this.pushStack(e)}});var K=/[^\x20\t\r\n\f]+/g;function L(a){var b={};return r.each(a.match(K)||[],function(a,c){b[c]=!0}),b}r.Callbacks=function(a){a="string"==typeof a?L(a):r.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h-1)f.splice(c,1),c<=h&&h--}),this},has:function(a){return a?r.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||b||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j};function M(a){return a}function N(a){throw a}function O(a,b,c){var d;try{a&&r.isFunction(d=a.promise)?d.call(a).done(b).fail(c):a&&r.isFunction(d=a.then)?d.call(a,b,c):b.call(void 0,a)}catch(a){c.call(void 0,a)}}r.extend({Deferred:function(b){var c=[["notify","progress",r.Callbacks("memory"),r.Callbacks("memory"),2],["resolve","done",r.Callbacks("once memory"),r.Callbacks("once memory"),0,"resolved"],["reject","fail",r.Callbacks("once memory"),r.Callbacks("once memory"),1,"rejected"]],d="pending",e={state:function(){return d},always:function(){return f.done(arguments).fail(arguments),this},"catch":function(a){return e.then(null,a)},pipe:function(){var a=arguments;return r.Deferred(function(b){r.each(c,function(c,d){var e=r.isFunction(a[d[4]])&&a[d[4]];f[d[1]](function(){var a=e&&e.apply(this,arguments);a&&r.isFunction(a.promise)?a.promise().progress(b.notify).done(b.resolve).fail(b.reject):b[d[0]+"With"](this,e?[a]:arguments)})}),a=null}).promise()},then:function(b,d,e){var f=0;function g(b,c,d,e){return function(){var h=this,i=arguments,j=function(){var a,j;if(!(b=f&&(d!==N&&(h=void 0,i=[a]),c.rejectWith(h,i))}};b?k():(r.Deferred.getStackHook&&(k.stackTrace=r.Deferred.getStackHook()),a.setTimeout(k))}}return r.Deferred(function(a){c[0][3].add(g(0,a,r.isFunction(e)?e:M,a.notifyWith)),c[1][3].add(g(0,a,r.isFunction(b)?b:M)),c[2][3].add(g(0,a,r.isFunction(d)?d:N))}).promise()},promise:function(a){return null!=a?r.extend(a,e):e}},f={};return r.each(c,function(a,b){var g=b[2],h=b[5];e[b[1]]=g.add,h&&g.add(function(){d=h},c[3-a][2].disable,c[0][2].lock),g.add(b[3].fire),f[b[0]]=function(){return f[b[0]+"With"](this===f?void 0:this,arguments),this},f[b[0]+"With"]=g.fireWith}),e.promise(f),b&&b.call(f,f),f},when:function(a){var b=arguments.length,c=b,d=Array(c),e=f.call(arguments),g=r.Deferred(),h=function(a){return function(c){d[a]=this,e[a]=arguments.length>1?f.call(arguments):c,--b||g.resolveWith(d,e)}};if(b<=1&&(O(a,g.done(h(c)).resolve,g.reject),"pending"===g.state()||r.isFunction(e[c]&&e[c].then)))return g.then();while(c--)O(e[c],h(c),g.reject);return g.promise()}});var P=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;r.Deferred.exceptionHook=function(b,c){a.console&&a.console.warn&&b&&P.test(b.name)&&a.console.warn("jQuery.Deferred exception: "+b.message,b.stack,c)},r.readyException=function(b){a.setTimeout(function(){throw b})};var Q=r.Deferred();r.fn.ready=function(a){return Q.then(a)["catch"](function(a){r.readyException(a)}),this},r.extend({isReady:!1,readyWait:1,holdReady:function(a){a?r.readyWait++:r.ready(!0)},ready:function(a){(a===!0?--r.readyWait:r.isReady)||(r.isReady=!0,a!==!0&&--r.readyWait>0||Q.resolveWith(d,[r]))}}),r.ready.then=Q.then;function R(){d.removeEventListener("DOMContentLoaded",R), +a.removeEventListener("load",R),r.ready()}"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(r.ready):(d.addEventListener("DOMContentLoaded",R),a.addEventListener("load",R));var S=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===r.type(c)){e=!0;for(h in c)S(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,r.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(r(a),c)})),b))for(;h1,null,!0)},removeData:function(a){return this.each(function(){W.remove(this,a)})}}),r.extend({queue:function(a,b,c){var d;if(a)return b=(b||"fx")+"queue",d=V.get(a,b),c&&(!d||r.isArray(c)?d=V.access(a,b,r.makeArray(c)):d.push(c)),d||[]},dequeue:function(a,b){b=b||"fx";var c=r.queue(a,b),d=c.length,e=c.shift(),f=r._queueHooks(a,b),g=function(){r.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return V.get(a,c)||V.access(a,c,{empty:r.Callbacks("once memory").add(function(){V.remove(a,[b+"queue",c])})})}}),r.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length\x20\t\r\n\f]+)/i,ka=/^$|\/(?:java|ecma)script/i,la={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};la.optgroup=la.option,la.tbody=la.tfoot=la.colgroup=la.caption=la.thead,la.th=la.td;function ma(a,b){var c;return c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[],void 0===b||b&&r.nodeName(a,b)?r.merge([a],c):c}function na(a,b){for(var c=0,d=a.length;c-1)e&&e.push(f);else if(j=r.contains(f.ownerDocument,f),g=ma(l.appendChild(f),"script"),j&&na(g),c){k=0;while(f=g[k++])ka.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),o.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="",o.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var qa=d.documentElement,ra=/^key/,sa=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,ta=/^([^.]*)(?:\.(.+)|)/;function ua(){return!0}function va(){return!1}function wa(){try{return d.activeElement}catch(a){}}function xa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)xa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=va;else if(!e)return a;return 1===f&&(g=e,e=function(a){return r().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=r.guid++)),a.each(function(){r.event.add(this,b,e,d,c)})}r.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.get(a);if(q){c.handler&&(f=c,c=f.handler,e=f.selector),e&&r.find.matchesSelector(qa,e),c.guid||(c.guid=r.guid++),(i=q.events)||(i=q.events={}),(g=q.handle)||(g=q.handle=function(b){return"undefined"!=typeof r&&r.event.triggered!==b.type?r.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(K)||[""],j=b.length;while(j--)h=ta.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n&&(l=r.event.special[n]||{},n=(e?l.delegateType:l.bindType)||n,l=r.event.special[n]||{},k=r.extend({type:n,origType:p,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&r.expr.match.needsContext.test(e),namespace:o.join(".")},f),(m=i[n])||(m=i[n]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,o,g)!==!1||a.addEventListener&&a.addEventListener(n,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),r.event.global[n]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,n,o,p,q=V.hasData(a)&&V.get(a);if(q&&(i=q.events)){b=(b||"").match(K)||[""],j=b.length;while(j--)if(h=ta.exec(b[j])||[],n=p=h[1],o=(h[2]||"").split(".").sort(),n){l=r.event.special[n]||{},n=(d?l.delegateType:l.bindType)||n,m=i[n]||[],h=h[2]&&new RegExp("(^|\\.)"+o.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&p!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,o,q.handle)!==!1||r.removeEvent(a,n,q.handle),delete i[n])}else for(n in i)r.event.remove(a,n+b[j],c,d,!0);r.isEmptyObject(i)&&V.remove(a,"handle events")}},dispatch:function(a){var b=r.event.fix(a),c,d,e,f,g,h,i=new Array(arguments.length),j=(V.get(this,"events")||{})[b.type]||[],k=r.event.special[b.type]||{};for(i[0]=b,c=1;c=1))for(;j!==this;j=j.parentNode||this)if(1===j.nodeType&&("click"!==a.type||j.disabled!==!0)){for(f=[],g={},c=0;c-1:r.find(e,this,null,[j]).length),g[e]&&f.push(d);f.length&&h.push({elem:j,handlers:f})}return j=this,i\x20\t\r\n\f]*)[^>]*)\/>/gi,za=/\s*$/g;function Da(a,b){return r.nodeName(a,"table")&&r.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function Ea(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function Fa(a){var b=Ba.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Ga(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(V.hasData(a)&&(f=V.access(a),g=V.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;c1&&"string"==typeof q&&!o.checkClone&&Aa.test(q))return a.each(function(e){var f=a.eq(e);s&&(b[0]=q.call(this,e,f.html())),Ia(f,b,c,d)});if(m&&(e=pa(b,a[0].ownerDocument,!1,a,d),f=e.firstChild,1===e.childNodes.length&&(e=f),f||d)){for(h=r.map(ma(e,"script"),Ea),i=h.length;l")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=r.contains(a.ownerDocument,a);if(!(o.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||r.isXMLDoc(a)))for(g=ma(h),f=ma(a),d=0,e=f.length;d0&&na(g,!i&&ma(a,"script")),h},cleanData:function(a){for(var b,c,d,e=r.event.special,f=0;void 0!==(c=a[f]);f++)if(T(c)){if(b=c[V.expando]){if(b.events)for(d in b.events)e[d]?r.event.remove(c,d):r.removeEvent(c,d,b.handle);c[V.expando]=void 0}c[W.expando]&&(c[W.expando]=void 0)}}}),r.fn.extend({detach:function(a){return Ja(this,a,!0)},remove:function(a){return Ja(this,a)},text:function(a){return S(this,function(a){return void 0===a?r.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=a)})},null,a,arguments.length)},append:function(){return Ia(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Da(this,a);b.appendChild(a)}})},prepend:function(){return Ia(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Da(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ia(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ia(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(r.cleanData(ma(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null!=a&&a,b=null==b?a:b,this.map(function(){return r.clone(this,a,b)})},html:function(a){return S(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!za.test(a)&&!la[(ja.exec(a)||["",""])[1].toLowerCase()]){a=r.htmlPrefilter(a);try{for(;c1)}});function Ya(a,b,c,d,e){return new Ya.prototype.init(a,b,c,d,e)}r.Tween=Ya,Ya.prototype={constructor:Ya,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||r.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(r.cssNumber[c]?"":"px")},cur:function(){var a=Ya.propHooks[this.prop];return a&&a.get?a.get(this):Ya.propHooks._default.get(this)},run:function(a){var b,c=Ya.propHooks[this.prop];return this.options.duration?this.pos=b=r.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ya.propHooks._default.set(this),this}},Ya.prototype.init.prototype=Ya.prototype,Ya.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=r.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){r.fx.step[a.prop]?r.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[r.cssProps[a.prop]]&&!r.cssHooks[a.prop]?a.elem[a.prop]=a.now:r.style(a.elem,a.prop,a.now+a.unit)}}},Ya.propHooks.scrollTop=Ya.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},r.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},r.fx=Ya.prototype.init,r.fx.step={};var Za,$a,_a=/^(?:toggle|show|hide)$/,ab=/queueHooks$/;function bb(){$a&&(a.requestAnimationFrame(bb),r.fx.tick())}function cb(){return a.setTimeout(function(){Za=void 0}),Za=r.now()}function db(a,b){var c,d=0,e={height:a};for(b=b?1:0;d<4;d+=2-b)c=ba[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function eb(a,b,c){for(var d,e=(hb.tweeners[b]||[]).concat(hb.tweeners["*"]),f=0,g=e.length;f1)},removeAttr:function(a){return this.each(function(){r.removeAttr(this,a)})}}),r.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?r.prop(a,b,c):(1===f&&r.isXMLDoc(a)||(e=r.attrHooks[b.toLowerCase()]||(r.expr.match.bool.test(b)?ib:void 0)), +void 0!==c?null===c?void r.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=r.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!o.radioValue&&"radio"===b&&r.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d=0,e=b&&b.match(K);if(e&&1===a.nodeType)while(c=e[d++])a.removeAttribute(c)}}),ib={set:function(a,b,c){return b===!1?r.removeAttr(a,c):a.setAttribute(c,c),c}},r.each(r.expr.match.bool.source.match(/\w+/g),function(a,b){var c=jb[b]||r.find.attr;jb[b]=function(a,b,d){var e,f,g=b.toLowerCase();return d||(f=jb[g],jb[g]=e,e=null!=c(a,b,d)?g:null,jb[g]=f),e}});var kb=/^(?:input|select|textarea|button)$/i,lb=/^(?:a|area)$/i;r.fn.extend({prop:function(a,b){return S(this,r.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[r.propFix[a]||a]})}}),r.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&r.isXMLDoc(a)||(b=r.propFix[b]||b,e=r.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=r.find.attr(a,"tabindex");return b?parseInt(b,10):kb.test(a.nodeName)||lb.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),o.optSelected||(r.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),r.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){r.propFix[this.toLowerCase()]=this});function mb(a){var b=a.match(K)||[];return b.join(" ")}function nb(a){return a.getAttribute&&a.getAttribute("class")||""}r.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).addClass(a.call(this,b,nb(this)))});if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=nb(c),d=1===c.nodeType&&" "+mb(e)+" "){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=mb(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(r.isFunction(a))return this.each(function(b){r(this).removeClass(a.call(this,b,nb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(K)||[];while(c=this[i++])if(e=nb(c),d=1===c.nodeType&&" "+mb(e)+" "){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=mb(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):r.isFunction(a)?this.each(function(c){r(this).toggleClass(a.call(this,c,nb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=r(this),f=a.match(K)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=nb(this),b&&V.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":V.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+mb(nb(c))+" ").indexOf(b)>-1)return!0;return!1}});var ob=/\r/g;r.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=r.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,r(this).val()):a,null==e?e="":"number"==typeof e?e+="":r.isArray(e)&&(e=r.map(e,function(a){return null==a?"":a+""})),b=r.valHooks[this.type]||r.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=r.valHooks[e.type]||r.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(ob,""):null==c?"":c)}}}),r.extend({valHooks:{option:{get:function(a){var b=r.find.attr(a,"value");return null!=b?b:mb(r.text(a))}},select:{get:function(a){var b,c,d,e=a.options,f=a.selectedIndex,g="select-one"===a.type,h=g?null:[],i=g?f+1:e.length;for(d=f<0?i:g?f:0;d-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),r.each(["radio","checkbox"],function(){r.valHooks[this]={set:function(a,b){if(r.isArray(b))return a.checked=r.inArray(r(a).val(),b)>-1}},o.checkOn||(r.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var pb=/^(?:focusinfocus|focusoutblur)$/;r.extend(r.event,{trigger:function(b,c,e,f){var g,h,i,j,k,m,n,o=[e||d],p=l.call(b,"type")?b.type:b,q=l.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!pb.test(p+r.event.triggered)&&(p.indexOf(".")>-1&&(q=p.split("."),p=q.shift(),q.sort()),k=p.indexOf(":")<0&&"on"+p,b=b[r.expando]?b:new r.Event(p,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=q.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:r.makeArray(c,[b]),n=r.event.special[p]||{},f||!n.trigger||n.trigger.apply(e,c)!==!1)){if(!f&&!n.noBubble&&!r.isWindow(e)){for(j=n.delegateType||p,pb.test(j+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),i=h;i===(e.ownerDocument||d)&&o.push(i.defaultView||i.parentWindow||a)}g=0;while((h=o[g++])&&!b.isPropagationStopped())b.type=g>1?j:n.bindType||p,m=(V.get(h,"events")||{})[b.type]&&V.get(h,"handle"),m&&m.apply(h,c),m=k&&h[k],m&&m.apply&&T(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=p,f||b.isDefaultPrevented()||n._default&&n._default.apply(o.pop(),c)!==!1||!T(e)||k&&r.isFunction(e[p])&&!r.isWindow(e)&&(i=e[k],i&&(e[k]=null),r.event.triggered=p,e[p](),r.event.triggered=void 0,i&&(e[k]=i)),b.result}},simulate:function(a,b,c){var d=r.extend(new r.Event,c,{type:a,isSimulated:!0});r.event.trigger(d,null,b)}}),r.fn.extend({trigger:function(a,b){return this.each(function(){r.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];if(c)return r.event.trigger(a,b,c,!0)}}),r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(a,b){r.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),r.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),o.focusin="onfocusin"in a,o.focusin||r.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){r.event.simulate(b,a.target,r.event.fix(a))};r.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=V.access(d,b);e||d.addEventListener(a,c,!0),V.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=V.access(d,b)-1;e?V.access(d,b,e):(d.removeEventListener(a,c,!0),V.remove(d,b))}}});var qb=a.location,rb=r.now(),sb=/\?/;r.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return c&&!c.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+b),c};var tb=/\[\]$/,ub=/\r?\n/g,vb=/^(?:submit|button|image|reset|file)$/i,wb=/^(?:input|select|textarea|keygen)/i;function xb(a,b,c,d){var e;if(r.isArray(b))r.each(b,function(b,e){c||tb.test(a)?d(a,e):xb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==r.type(b))d(a,b);else for(e in b)xb(a+"["+e+"]",b[e],c,d)}r.param=function(a,b){var c,d=[],e=function(a,b){var c=r.isFunction(b)?b():b;d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(null==c?"":c)};if(r.isArray(a)||a.jquery&&!r.isPlainObject(a))r.each(a,function(){e(this.name,this.value)});else for(c in a)xb(c,a[c],b,e);return d.join("&")},r.fn.extend({serialize:function(){return r.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=r.prop(this,"elements");return a?r.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!r(this).is(":disabled")&&wb.test(this.nodeName)&&!vb.test(a)&&(this.checked||!ia.test(a))}).map(function(a,b){var c=r(this).val();return null==c?null:r.isArray(c)?r.map(c,function(a){return{name:b.name,value:a.replace(ub,"\r\n")}}):{name:b.name,value:c.replace(ub,"\r\n")}}).get()}});var yb=/%20/g,zb=/#.*$/,Ab=/([?&])_=[^&]*/,Bb=/^(.*?):[ \t]*([^\r\n]*)$/gm,Cb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Db=/^(?:GET|HEAD)$/,Eb=/^\/\//,Fb={},Gb={},Hb="*/".concat("*"),Ib=d.createElement("a");Ib.href=qb.href;function Jb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(K)||[];if(r.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Kb(a,b,c,d){var e={},f=a===Gb;function g(h){var i;return e[h]=!0,r.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Lb(a,b){var c,d,e=r.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&r.extend(!0,a,d),a}function Mb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}if(f)return f!==i[0]&&i.unshift(f),c[f]}function Nb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}r.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:qb.href,type:"GET",isLocal:Cb.test(qb.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Hb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":r.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Lb(Lb(a,r.ajaxSettings),b):Lb(r.ajaxSettings,a)},ajaxPrefilter:Jb(Fb),ajaxTransport:Jb(Gb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m,n,o=r.ajaxSetup({},c),p=o.context||o,q=o.context&&(p.nodeType||p.jquery)?r(p):r.event,s=r.Deferred(),t=r.Callbacks("once memory"),u=o.statusCode||{},v={},w={},x="canceled",y={readyState:0,getResponseHeader:function(a){var b;if(k){if(!h){h={};while(b=Bb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return k?g:null},setRequestHeader:function(a,b){return null==k&&(a=w[a.toLowerCase()]=w[a.toLowerCase()]||a,v[a]=b),this},overrideMimeType:function(a){return null==k&&(o.mimeType=a),this},statusCode:function(a){var b;if(a)if(k)y.always(a[y.status]);else for(b in a)u[b]=[u[b],a[b]];return this},abort:function(a){var b=a||x;return e&&e.abort(b),A(0,b),this}};if(s.promise(y),o.url=((b||o.url||qb.href)+"").replace(Eb,qb.protocol+"//"),o.type=c.method||c.type||o.method||o.type,o.dataTypes=(o.dataType||"*").toLowerCase().match(K)||[""],null==o.crossDomain){j=d.createElement("a");try{j.href=o.url,j.href=j.href,o.crossDomain=Ib.protocol+"//"+Ib.host!=j.protocol+"//"+j.host}catch(z){o.crossDomain=!0}}if(o.data&&o.processData&&"string"!=typeof o.data&&(o.data=r.param(o.data,o.traditional)),Kb(Fb,o,c,y),k)return y;l=r.event&&o.global,l&&0===r.active++&&r.event.trigger("ajaxStart"),o.type=o.type.toUpperCase(),o.hasContent=!Db.test(o.type),f=o.url.replace(zb,""),o.hasContent?o.data&&o.processData&&0===(o.contentType||"").indexOf("application/x-www-form-urlencoded")&&(o.data=o.data.replace(yb,"+")):(n=o.url.slice(f.length),o.data&&(f+=(sb.test(f)?"&":"?")+o.data,delete o.data),o.cache===!1&&(f=f.replace(Ab,"$1"),n=(sb.test(f)?"&":"?")+"_="+rb++ +n),o.url=f+n),o.ifModified&&(r.lastModified[f]&&y.setRequestHeader("If-Modified-Since",r.lastModified[f]),r.etag[f]&&y.setRequestHeader("If-None-Match",r.etag[f])),(o.data&&o.hasContent&&o.contentType!==!1||c.contentType)&&y.setRequestHeader("Content-Type",o.contentType),y.setRequestHeader("Accept",o.dataTypes[0]&&o.accepts[o.dataTypes[0]]?o.accepts[o.dataTypes[0]]+("*"!==o.dataTypes[0]?", "+Hb+"; q=0.01":""):o.accepts["*"]);for(m in o.headers)y.setRequestHeader(m,o.headers[m]);if(o.beforeSend&&(o.beforeSend.call(p,y,o)===!1||k))return y.abort();if(x="abort",t.add(o.complete),y.done(o.success),y.fail(o.error),e=Kb(Gb,o,c,y)){if(y.readyState=1,l&&q.trigger("ajaxSend",[y,o]),k)return y;o.async&&o.timeout>0&&(i=a.setTimeout(function(){y.abort("timeout")},o.timeout));try{k=!1,e.send(v,A)}catch(z){if(k)throw z;A(-1,z)}}else A(-1,"No Transport");function A(b,c,d,h){var j,m,n,v,w,x=c;k||(k=!0,i&&a.clearTimeout(i),e=void 0,g=h||"",y.readyState=b>0?4:0,j=b>=200&&b<300||304===b,d&&(v=Mb(o,y,d)),v=Nb(o,v,y,j),j?(o.ifModified&&(w=y.getResponseHeader("Last-Modified"),w&&(r.lastModified[f]=w),w=y.getResponseHeader("etag"),w&&(r.etag[f]=w)),204===b||"HEAD"===o.type?x="nocontent":304===b?x="notmodified":(x=v.state,m=v.data,n=v.error,j=!n)):(n=x,!b&&x||(x="error",b<0&&(b=0))),y.status=b,y.statusText=(c||x)+"",j?s.resolveWith(p,[m,x,y]):s.rejectWith(p,[y,x,n]),y.statusCode(u),u=void 0,l&&q.trigger(j?"ajaxSuccess":"ajaxError",[y,o,j?m:n]),t.fireWith(p,[y,x]),l&&(q.trigger("ajaxComplete",[y,o]),--r.active||r.event.trigger("ajaxStop")))}return y},getJSON:function(a,b,c){return r.get(a,b,c,"json")},getScript:function(a,b){return r.get(a,void 0,b,"script")}}),r.each(["get","post"],function(a,b){r[b]=function(a,c,d,e){return r.isFunction(c)&&(e=e||d,d=c,c=void 0),r.ajax(r.extend({url:a,type:b,dataType:e,data:c,success:d},r.isPlainObject(a)&&a))}}),r._evalUrl=function(a){return r.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},r.fn.extend({wrapAll:function(a){var b;return this[0]&&(r.isFunction(a)&&(a=a.call(this[0])),b=r(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this},wrapInner:function(a){return r.isFunction(a)?this.each(function(b){r(this).wrapInner(a.call(this,b))}):this.each(function(){var b=r(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=r.isFunction(a);return this.each(function(c){r(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(a){return this.parent(a).not("body").each(function(){r(this).replaceWith(this.childNodes)}),this}}),r.expr.pseudos.hidden=function(a){return!r.expr.pseudos.visible(a)},r.expr.pseudos.visible=function(a){return!!(a.offsetWidth||a.offsetHeight||a.getClientRects().length)},r.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Ob={0:200,1223:204},Pb=r.ajaxSettings.xhr();o.cors=!!Pb&&"withCredentials"in Pb,o.ajax=Pb=!!Pb,r.ajaxTransport(function(b){var c,d;if(o.cors||Pb&&!b.crossDomain)return{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Ob[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}}),r.ajaxPrefilter(function(a){a.crossDomain&&(a.contents.script=!1)}),r.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return r.globalEval(a),a}}}),r.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),r.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=r(" - diff --git a/_sass/layout/toc.scss b/_sass/layout/toc.scss index c4d9556079..7ac4716277 100644 --- a/_sass/layout/toc.scss +++ b/_sass/layout/toc.scss @@ -3,6 +3,14 @@ //------------------------------------------------ .sidebar-toc-wrapper { + position: -webkit-sticky; + position: sticky; + top: 0; + + @include bp(large) { + position: relative; + } + @include bp(medium) { display: none; } diff --git a/resources/js/functions.js b/resources/js/functions.js index ff9d0f7676..9e9fd92070 100644 --- a/resources/js/functions.js +++ b/resources/js/functions.js @@ -304,27 +304,9 @@ $(document).ready(function() { autoId: true, numerate: false }); - toggleStickyToc(); } }); -$(window).resize(function() { - toggleStickyToc(); -}); - -var toggleStickyToc = function() { - if ($("#sidebar-toc").length) { - if ($(window).width() <= 992) { - $(".sidebar-toc-wrapper").unstick(); - } else { - $(".sidebar-toc-wrapper").sticky({ - topSpacing: 0, - bottomSpacing: 500 - }); - } - } -} - // Language dropdown function DropDown(el) { this.dd = el; diff --git a/resources/js/vendor/jquery.sticky.js b/resources/js/vendor/jquery.sticky.js deleted file mode 100644 index f50486f357..0000000000 --- a/resources/js/vendor/jquery.sticky.js +++ /dev/null @@ -1,287 +0,0 @@ -// Sticky Plugin v1.0.4 for jQuery -// ============= -// Author: Anthony Garand -// Improvements by German M. Bravo (Kronuz) and Ruud Kamphuis (ruudk) -// Improvements by Leonardo C. Daronco (daronco) -// Created: 02/14/2011 -// Date: 07/20/2015 -// Website: http://stickyjs.com/ -// Description: Makes an element on the page stick on the screen as you scroll -// It will only set the 'top' and 'position' of your element, you -// might need to adjust the width in some cases. - -(function (factory) { - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(['jquery'], factory); - } else if (typeof module === 'object' && module.exports) { - // Node/CommonJS - module.exports = factory(require('jquery')); - } else { - // Browser globals - factory(jQuery); - } -}(function ($) { - var slice = Array.prototype.slice; // save ref to original slice() - var splice = Array.prototype.splice; // save ref to original slice() - - var defaults = { - topSpacing: 0, - bottomSpacing: 0, - className: 'is-sticky', - wrapperClassName: 'sticky-wrapper', - center: false, - getWidthFrom: '', - widthFromWrapper: true, // works only when .getWidthFrom is empty - responsiveWidth: false, - zIndex: 'auto' - }, - $window = $(window), - $document = $(document), - sticked = [], - windowHeight = $window.height(), - scroller = function() { - var scrollTop = $window.scrollTop(), - documentHeight = $document.height(), - dwh = documentHeight - windowHeight, - extra = (scrollTop > dwh) ? dwh - scrollTop : 0; - - for (var i = 0, l = sticked.length; i < l; i++) { - var s = sticked[i], - elementTop = s.stickyWrapper.offset().top, - etse = elementTop - s.topSpacing - extra; - - //update height in case of dynamic content - s.stickyWrapper.css('height', s.stickyElement.outerHeight()); - - if (scrollTop <= etse) { - if (s.currentTop !== null) { - s.stickyElement - .css({ - 'width': '', - 'position': '', - 'top': '', - 'z-index': '' - }); - s.stickyElement.parent().removeClass(s.className); - s.stickyElement.trigger('sticky-end', [s]); - s.currentTop = null; - } - } - else { - var newTop = documentHeight - s.stickyElement.outerHeight() - - s.topSpacing - s.bottomSpacing - scrollTop - extra; - if (newTop < 0) { - newTop = newTop + s.topSpacing; - } else { - newTop = s.topSpacing; - } - if (s.currentTop !== newTop) { - var newWidth; - if (s.getWidthFrom) { - newWidth = $(s.getWidthFrom).width() || null; - } else if (s.widthFromWrapper) { - newWidth = s.stickyWrapper.width(); - } - if (newWidth == null) { - newWidth = s.stickyElement.width(); - } - s.stickyElement - .css('width', newWidth) - .css('position', 'fixed') - .css('top', newTop) - .css('z-index', s.zIndex); - - s.stickyElement.parent().addClass(s.className); - - if (s.currentTop === null) { - s.stickyElement.trigger('sticky-start', [s]); - } else { - // sticky is started but it have to be repositioned - s.stickyElement.trigger('sticky-update', [s]); - } - - if (s.currentTop === s.topSpacing && s.currentTop > newTop || s.currentTop === null && newTop < s.topSpacing) { - // just reached bottom || just started to stick but bottom is already reached - s.stickyElement.trigger('sticky-bottom-reached', [s]); - } else if(s.currentTop !== null && newTop === s.topSpacing && s.currentTop < newTop) { - // sticky is started && sticked at topSpacing && overflowing from top just finished - s.stickyElement.trigger('sticky-bottom-unreached', [s]); - } - - s.currentTop = newTop; - } - - // Check if sticky has reached end of container and stop sticking - var stickyWrapperContainer = s.stickyWrapper.parent(); - var unstick = (s.stickyElement.offset().top + s.stickyElement.outerHeight() >= stickyWrapperContainer.offset().top + stickyWrapperContainer.outerHeight()) && (s.stickyElement.offset().top <= s.topSpacing); - - if( unstick ) { - s.stickyElement - .css('position', 'absolute') - .css('top', '') - .css('bottom', 0) - .css('z-index', ''); - } else { - s.stickyElement - .css('position', 'fixed') - .css('top', newTop) - .css('bottom', '') - .css('z-index', s.zIndex); - } - } - } - }, - resizer = function() { - windowHeight = $window.height(); - - for (var i = 0, l = sticked.length; i < l; i++) { - var s = sticked[i]; - var newWidth = null; - if (s.getWidthFrom) { - if (s.responsiveWidth) { - newWidth = $(s.getWidthFrom).width(); - } - } else if(s.widthFromWrapper) { - newWidth = s.stickyWrapper.width(); - } - if (newWidth != null) { - s.stickyElement.css('width', newWidth); - } - } - }, - methods = { - init: function(options) { - return this.each(function() { - var o = $.extend({}, defaults, options); - var stickyElement = $(this); - - var stickyId = stickyElement.attr('id'); - var wrapperId = stickyId ? stickyId + '-' + defaults.wrapperClassName : defaults.wrapperClassName; - var wrapper = $('
') - .attr('id', wrapperId) - .addClass(o.wrapperClassName); - - stickyElement.wrapAll(function() { - if ($(this).parent("#" + wrapperId).length == 0) { - return wrapper; - } -}); - - var stickyWrapper = stickyElement.parent(); - - if (o.center) { - stickyWrapper.css({width:stickyElement.outerWidth(),marginLeft:"auto",marginRight:"auto"}); - } - - if (stickyElement.css("float") === "right") { - stickyElement.css({"float":"none"}).parent().css({"float":"right"}); - } - - o.stickyElement = stickyElement; - o.stickyWrapper = stickyWrapper; - o.currentTop = null; - - sticked.push(o); - - methods.setWrapperHeight(this); - methods.setupChangeListeners(this); - }); - }, - - setWrapperHeight: function(stickyElement) { - var element = $(stickyElement); - var stickyWrapper = element.parent(); - if (stickyWrapper) { - stickyWrapper.css('height', element.outerHeight()); - } - }, - - setupChangeListeners: function(stickyElement) { - if (window.MutationObserver) { - var mutationObserver = new window.MutationObserver(function(mutations) { - if (mutations[0].addedNodes.length || mutations[0].removedNodes.length) { - methods.setWrapperHeight(stickyElement); - } - }); - mutationObserver.observe(stickyElement, {subtree: true, childList: true}); - } else { - if (window.addEventListener) { - stickyElement.addEventListener('DOMNodeInserted', function() { - methods.setWrapperHeight(stickyElement); - }, false); - stickyElement.addEventListener('DOMNodeRemoved', function() { - methods.setWrapperHeight(stickyElement); - }, false); - } else if (window.attachEvent) { - stickyElement.attachEvent('onDOMNodeInserted', function() { - methods.setWrapperHeight(stickyElement); - }); - stickyElement.attachEvent('onDOMNodeRemoved', function() { - methods.setWrapperHeight(stickyElement); - }); - } - } - }, - update: scroller, - unstick: function(options) { - return this.each(function() { - var that = this; - var unstickyElement = $(that); - - var removeIdx = -1; - var i = sticked.length; - while (i-- > 0) { - if (sticked[i].stickyElement.get(0) === that) { - splice.call(sticked,i,1); - removeIdx = i; - } - } - if(removeIdx !== -1) { - unstickyElement.unwrap(); - unstickyElement - .css({ - 'width': '', - 'position': '', - 'top': '', - 'float': '', - 'z-index': '' - }) - ; - } - }); - } - }; - - // should be more efficient than using $window.scroll(scroller) and $window.resize(resizer): - if (window.addEventListener) { - window.addEventListener('scroll', scroller, false); - window.addEventListener('resize', resizer, false); - } else if (window.attachEvent) { - window.attachEvent('onscroll', scroller); - window.attachEvent('onresize', resizer); - } - - $.fn.sticky = function(method) { - if (methods[method]) { - return methods[method].apply(this, slice.call(arguments, 1)); - } else if (typeof method === 'object' || !method ) { - return methods.init.apply( this, arguments ); - } else { - $.error('Method ' + method + ' does not exist on jQuery.sticky'); - } - }; - - $.fn.unstick = function(method) { - if (methods[method]) { - return methods[method].apply(this, slice.call(arguments, 1)); - } else if (typeof method === 'object' || !method ) { - return methods.unstick.apply( this, arguments ); - } else { - $.error('Method ' + method + ' does not exist on jQuery.sticky'); - } - }; - $(function() { - setTimeout(scroller, 0); - }); -})); From 022d3a49b9e677a60e5cefed38365dc667e4cb28 Mon Sep 17 00:00:00 2001 From: Sam Zaydel Date: Mon, 18 Mar 2019 07:03:59 -0700 Subject: [PATCH 0439/3075] Extra 'not' in sentence in Trait Traversable --- _overviews/FAQ/collections.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_overviews/FAQ/collections.md b/_overviews/FAQ/collections.md index 65f9f3d5a1..b044191727 100644 --- a/_overviews/FAQ/collections.md +++ b/_overviews/FAQ/collections.md @@ -171,8 +171,8 @@ Traversible objects can be finite or infinite. An example of an infinite traversable object is the stream of natural numbers `Stream.from(0)`. The method `hasDefiniteSize` indicates whether a collection is possibly infinite. If `hasDefiniteSize` returns true, the collection is certainly finite. If it -returns false, the collection has not been not fully elaborated yet, so it -might be infinite or finite. +returns false, the collection has not been fully elaborated yet, so it might +be infinite or finite. This class defines methods which can be efficiently implemented in terms of `foreach` (over 40 of them). From 152516a1b3198f810fee43622040a7d1b444b5eb Mon Sep 17 00:00:00 2001 From: Xztty Date: Thu, 21 Mar 2019 14:14:01 +0800 Subject: [PATCH 0440/3075] replace JavaConversions to JavaConverters from scala 2.12.0 the JavaConversions is marked as deprecated class. And it's recommended to use JavaConverters --- ...ersions-between-java-and-scala-collections.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/_zh-cn/overviews/collections/conversions-between-java-and-scala-collections.md b/_zh-cn/overviews/collections/conversions-between-java-and-scala-collections.md index af302dd49f..9b8e44daf0 100644 --- a/_zh-cn/overviews/collections/conversions-between-java-and-scala-collections.md +++ b/_zh-cn/overviews/collections/conversions-between-java-and-scala-collections.md @@ -25,20 +25,20 @@ language: zh-cn mutable.Map <=> java.util.Map mutable.ConcurrentMap <=> java.util.concurrent.ConcurrentMap -使用这些转换很简单,只需从JavaConversions对象中import它们即可。 +使用这些转换很简单,只需从JavaConverters对象中import它们即可。 - scala> import collection.JavaConversions._ - import collection.Java.Conversions._ + scala> import collection.JavaConverters._ + import collection.JavaConverters._ -import之后,就可以在Scala容器和与之对应的Java容器之间进行隐式转换了 +import之后,通过扩展方法 asScala 和 asJava 就可以在Scala容器和与之对应的Java容器之间进行隐式转换了 scala> import collection.mutable._ import collection.mutable._ - scala> val jul: java.util.List[Int] = ArrayBuffer(1, 2, 3) + scala> val jul: java.util.List[Int] = ArrayBuffer(1, 2, 3).asJava jul: java.util.List[Int] = [1, 2, 3] - scala> val buf: Seq[Int] = jul + scala> val buf: Seq[Int] = jul.asScala buf: scala.collection.mutable.Seq[Int] = ArrayBuffer(1, 2, 3) - scala> val m: java.util.Map[String, Int] = HashMap("abc" -> 1, "hello" -> 2) + scala> val m: java.util.Map[String, Int] = HashMap("abc" -> 1, "hello" -> 2).asJava m: java.util.Map[String, Int] = {hello=2, abc=1} 在Scala内部,这些转换是通过一系列“包装”对象完成的,这些对象会将相应的方法调用转发至底层的容器对象。所以容器不会在Java和Scala之间拷贝来拷贝去。一个值得注意的特性是,如果你将一个Java容器转换成其对应的Scala容器,然后再将其转换回同样的Java容器,最终得到的是一个和一开始完全相同的容器对象(译注:这里的相同意味着这两个对象实际上是指向同一片内存区域的引用,容器转换过程中没有任何的拷贝发生)。 @@ -52,7 +52,7 @@ import之后,就可以在Scala容器和与之对应的Java容器之间进行 因为Java并未区分可变容器不可变容器类型,所以,虽然能将`scala.immutable.List`转换成`java.util.List`,但所有的修改操作都会抛出“UnsupportedOperationException”。参见下例: - scala> jul = List(1, 2, 3) + scala> jul = List(1, 2, 3).asJava jul: java.util.List[Int] = [1, 2, 3] scala> jul.add(7) java.lang.UnsupportedOperationException From 06464d4f919912051141a055c3ba5ece6c7bf99f Mon Sep 17 00:00:00 2001 From: salim7 Date: Tue, 26 Mar 2019 10:49:15 +0100 Subject: [PATCH 0441/3075] Fixed Typo --- .../parallel-collections/conversions.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/_overviews/parallel-collections/conversions.md b/_overviews/parallel-collections/conversions.md index 9997c5539a..f4d42d446c 100644 --- a/_overviews/parallel-collections/conversions.md +++ b/_overviews/parallel-collections/conversions.md @@ -66,16 +66,16 @@ into a `ParX` collection. Here is a summary of all conversion methods: -| Method | Return Type | -| -------------- | -------------- | -| `toArray` | `Array` | -| `toList` | `List` | -| `toIndexedSeq` | `IndexedSeq` | -| `toStream` | `Stream` | -| `toIterator` | `Iterator` | -| `toBuffer` | `Buffer` | -| `toTraversable`| `GenTraverable`| -| `toIterable` | `ParIterable` | -| `toSeq` | `ParSeq` | -| `toSet` | `ParSet` | -| `toMap` | `ParMap` | +| Method | Return Type | +| -------------- | --------------- | +| `toArray` | `Array` | +| `toList` | `List` | +| `toIndexedSeq` | `IndexedSeq` | +| `toStream` | `Stream` | +| `toIterator` | `Iterator` | +| `toBuffer` | `Buffer` | +| `toTraversable`| `GenTraversable`| +| `toIterable` | `ParIterable` | +| `toSeq` | `ParSeq` | +| `toSet` | `ParSet` | +| `toMap` | `ParMap` | From 6420a94d859c84fdabc3f2b95aab5b73de6d8a49 Mon Sep 17 00:00:00 2001 From: Long Sun Date: Tue, 26 Mar 2019 14:20:49 +0800 Subject: [PATCH 0442/3075] Fix typo --- _zh-cn/tour/basics.md | 2 +- _zh-cn/tour/classes.md | 2 +- _zh-cn/tour/unified-types.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_zh-cn/tour/basics.md b/_zh-cn/tour/basics.md index b63a482e41..82ac4a3f27 100644 --- a/_zh-cn/tour/basics.md +++ b/_zh-cn/tour/basics.md @@ -25,7 +25,7 @@ previous-page: tour-of-scala 这是一种简单的、零设置的方法来实践Scala的代码片段。 -这篇文档中的大部分代码示例与 ScalaFiddle 进行了集成,可以通过点击 “Run” 按钮即来直接运行 Scale 代码。 +这篇文档中的大部分代码示例与 ScalaFiddle 进行了集成,可以通过点击 “Run” 按钮即来直接运行 Scala 代码。 ## 表达式 diff --git a/_zh-cn/tour/classes.md b/_zh-cn/tour/classes.md index 1f6026a3aa..e916677681 100644 --- a/_zh-cn/tour/classes.md +++ b/_zh-cn/tour/classes.md @@ -95,7 +95,7 @@ point1.y = 101 // prints the warning ``` 在这个版本的`Point`类中,数据存在私有变量`_x`和`_y`中。`def x`和`def y`方法用于访问私有数据。`def x_=`和`def y_=`是为了验证和给`_x`和`_y`赋值。注意下对于setter方法的特殊语法:这个方法在getter方法的后面加上`_=`,后面跟着参数。 -主构造方法中带有`val`和`var`的参数时公有的。然而由于`val`是不可变的,所以不能像下面这样去使用。 +主构造方法中带有`val`和`var`的参数是公有的。然而由于`val`是不可变的,所以不能像下面这样去使用。 ``` class Point(val x: Int, val y: Int) val point = new Point(1, 2) diff --git a/_zh-cn/tour/unified-types.md b/_zh-cn/tour/unified-types.md index 4ddd6d01ac..d5bacaa87d 100644 --- a/_zh-cn/tour/unified-types.md +++ b/_zh-cn/tour/unified-types.md @@ -42,7 +42,7 @@ val list: List[Any] = List( list.foreach(element => println(element)) ``` -这里定义了一个类型`List`的变量`list`。这个列表里由多种类型进行初始化,但是它们都是`scala.Any`的实例,所以可以把它们加入到列表中。 +这里定义了一个类型`List`的变量`list`。这个列表里由多种类型进行初始化,但是它们都是`scala.Any`的实例,所以可以把它们加入到列表中。 下面是程序的输出: From 7166149b60df844d95da092ccb18c78a08b39552 Mon Sep 17 00:00:00 2001 From: Salim D Date: Tue, 26 Mar 2019 12:25:59 +0100 Subject: [PATCH 0443/3075] Fixed Typo in Japanese Translation --- .../parallel-collections/conversions.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/_ja/overviews/parallel-collections/conversions.md b/_ja/overviews/parallel-collections/conversions.md index 73345f4fd9..636f6885b4 100644 --- a/_ja/overviews/parallel-collections/conversions.md +++ b/_ja/overviews/parallel-collections/conversions.md @@ -47,16 +47,16 @@ language: ja 以下の表に全ての変換をまとめる: -| メソッド | 戻り値の型 | -| -------------- | -------------- | -| `toArray` | `Array` | -| `toList` | `List` | -| `toIndexedSeq` | `IndexedSeq` | -| `toStream` | `Stream` | -| `toIterator` | `Iterator` | -| `toBuffer` | `Buffer` | -| `toTraversable`| `GenTraverable`| -| `toIterable` | `ParIterable` | -| `toSeq` | `ParSeq` | -| `toSet` | `ParSet` | -| `toMap` | `ParMap` | +| メソッド | 戻り値の型 | +| -------------- | --------------- | +| `toArray` | `Array` | +| `toList` | `List` | +| `toIndexedSeq` | `IndexedSeq` | +| `toStream` | `Stream` | +| `toIterator` | `Iterator` | +| `toBuffer` | `Buffer` | +| `toTraversable`| `GenTraversable`| +| `toIterable` | `ParIterable` | +| `toSeq` | `ParSeq` | +| `toSet` | `ParSet` | +| `toMap` | `ParMap` | From e56e2f3c57e2d8552ea1b0804f7480d48aecd6b5 Mon Sep 17 00:00:00 2001 From: Salim D Date: Tue, 26 Mar 2019 12:27:00 +0100 Subject: [PATCH 0444/3075] Fixed Typo in Chinese Translation --- _zh-cn/overviews/parallel-collections/conversions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_zh-cn/overviews/parallel-collections/conversions.md b/_zh-cn/overviews/parallel-collections/conversions.md index 788ca55630..6f13fd3491 100644 --- a/_zh-cn/overviews/parallel-collections/conversions.md +++ b/_zh-cn/overviews/parallel-collections/conversions.md @@ -46,7 +46,7 @@ language: zh-cn |toStream | Stream | |toIterator | Iterator | |toBuffer | Buffer | -|toTraversable | GenTraverable | +|toTraversable | GenTraversable | |toIterable | ParIterable | |toSeq | ParSeq | |toSet | ParSet | From 86fe85797f87dbf547487d6236d1ead6e2c97abb Mon Sep 17 00:00:00 2001 From: Salim D Date: Tue, 26 Mar 2019 12:27:56 +0100 Subject: [PATCH 0445/3075] Fixed Typo in Spanish Translation --- .../parallel-collections/conversions.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/_es/overviews/parallel-collections/conversions.md b/_es/overviews/parallel-collections/conversions.md index 8461a2f9aa..ec836d0338 100644 --- a/_es/overviews/parallel-collections/conversions.md +++ b/_es/overviews/parallel-collections/conversions.md @@ -61,16 +61,16 @@ en una colección `ParX` A continuación se muestra un resumen de todos los métodos de conversión: -| método | Tipo de Retorno| -| -------------- | -------------- | -| `toArray` | `Array` | -| `toList` | `List` | -| `toIndexedSeq` | `IndexedSeq` | -| `toStream` | `Stream` | -| `toIterator` | `Iterator` | -| `toBuffer` | `Buffer` | -| `toTraversable`| `GenTraverable`| -| `toIterable` | `ParIterable` | -| `toSeq` | `ParSeq` | -| `toSet` | `ParSet` | -| `toMap` | `ParMap` | +| método | Tipo de Retorno | +| -------------- | --------------- | +| `toArray` | `Array` | +| `toList` | `List` | +| `toIndexedSeq` | `IndexedSeq` | +| `toStream` | `Stream` | +| `toIterator` | `Iterator` | +| `toBuffer` | `Buffer` | +| `toTraversable`| `GenTraversable`| +| `toIterable` | `ParIterable` | +| `toSeq` | `ParSeq` | +| `toSet` | `ParSet` | +| `toMap` | `ParMap` | From 2f5d77fb3657919a3aa0bc7b04e7ee00b3a49d19 Mon Sep 17 00:00:00 2001 From: Salim D Date: Tue, 26 Mar 2019 12:29:18 +0100 Subject: [PATCH 0446/3075] Fixed Typo in Russian Translation --- .../parallel-collections/conversions.md | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/_ru/overviews/parallel-collections/conversions.md b/_ru/overviews/parallel-collections/conversions.md index 8579774ec9..114f2d8986 100644 --- a/_ru/overviews/parallel-collections/conversions.md +++ b/_ru/overviews/parallel-collections/conversions.md @@ -38,16 +38,16 @@ num: 3 Ниже приведена сводная таблица всех методов преобразования: -| Метод | Тип возвращаемого значения | -| -------------- | -------------------------- | -| `toArray` | `Array` | -| `toList` | `List` | -| `toIndexedSeq` | `IndexedSeq` | -| `toStream` | `Stream` | -| `toIterator` | `Iterator` | -| `toBuffer` | `Buffer` | -| `toTraversable`| `GenTraverable` | -| `toIterable` | `ParIterable` | -| `toSeq` | `ParSeq` | -| `toSet` | `ParSet` | -| `toMap` | `ParMap` | +| Метод | Тип возвращаемого значения | +| -------------- | --------------------------- | +| `toArray` | `Array` | +| `toList` | `List` | +| `toIndexedSeq` | `IndexedSeq` | +| `toStream` | `Stream` | +| `toIterator` | `Iterator` | +| `toBuffer` | `Buffer` | +| `toTraversable`| `GenTraversable` | +| `toIterable` | `ParIterable` | +| `toSeq` | `ParSeq` | +| `toSet` | `ParSet` | +| `toMap` | `ParMap` | From 16d636c1509d374a328c58518c282ba04fb52c63 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Mon, 8 Apr 2019 08:36:19 +0000 Subject: [PATCH 0447/3075] add RC1 Scaladoc --- api/all.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/api/all.md b/api/all.md index d629074504..50c5bea6bc 100644 --- a/api/all.md +++ b/api/all.md @@ -5,6 +5,7 @@ includeTOC: true --- ## Latest releases + * Scala 2.12.8 * [Library API](https://www.scala-lang.org/api/2.12.8/) * [Compiler API](https://www.scala-lang.org/api/2.12.8/scala-compiler/scala/) @@ -25,6 +26,13 @@ includeTOC: true * [Continuations API](https://www.scala-lang.org/files/archive/api/2.11.12/scala-continuations-library/#scala.util.continuations.package) * [Scala 2.10.7](https://www.scala-lang.org/api/2.10.7/) +## Prereleases + +* Scala 2.13.0-RC1 + * [Library API](https://www.scala-lang.org/api/2.13.0-RC1/) + * [Compiler API](https://www.scala-lang.org/api/2.13.0-RC1/scala-compiler/scala/) + * [Reflection API](https://www.scala-lang.org/api/2.13.0-RC1/scala-reflect/scala/reflect/) + ## Nightly builds * Scala 2.13.x From 151a87ec0d501fe70702cd1193597e8ac5fa1232 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Tue, 9 Apr 2019 13:38:35 +0200 Subject: [PATCH 0448/3075] Adapt architecture of collections to latest 2.13 changes --- .../architecture-of-scala-213-collections.md | 33 ++-- .../core/custom-collection-operations.md | 2 +- _overviews/core/custom-collections.md | 166 ++++++++++-------- 3 files changed, 105 insertions(+), 96 deletions(-) diff --git a/_overviews/core/architecture-of-scala-213-collections.md b/_overviews/core/architecture-of-scala-213-collections.md index 5144b83f45..557c8c0258 100644 --- a/_overviews/core/architecture-of-scala-213-collections.md +++ b/_overviews/core/architecture-of-scala-213-collections.md @@ -280,13 +280,13 @@ implementations of `filter` and `map`: trait IterableOps[+A, +CC[_], +C] { def filter(pred: A => Boolean): C = - fromSpecificIterable(new View.Filter(this, pred)) + fromSpecific(new View.Filter(this, pred)) def map[B](f: A => B): CC[B] = - fromIterable(new View.Map(this, f)) + from(new View.Map(this, f)) - protected def fromSpecificIterable(coll: Iterable[A]): C - protected def fromIterable[E](it: Iterable[E]): CC[E] + protected def fromSpecific(coll: IterableOnce[A]): C + protected def from[E](it: IterableOnce[E]): CC[E] } ~~~ @@ -294,25 +294,25 @@ Let’s detail the implementation of `filter`, step by step: - the instantiation of `View.Filter` creates a (non-strict) `View` that filters the elements of the underlying collection ; -- the call to `fromSpecificIterable` turns the `View` into a concrete - collection `C`. The implementation of `fromSpecificIterable` is left to +- the call to `fromSpecific` turns the `View` into a concrete + collection `C`. The implementation of `fromSpecific` is left to concrete collections: they can decide to evaluate in a strict or non-strict way the elements resulting from the operation. The implementation of `map` is similar, excepted that instead of using -`fromSpecificIterable` it uses `fromIterable` which takes as parameter an +`fromSpecific` it uses `from` which takes as parameter an iterable whose element type `E` is arbitrary. -Actually, `fromIterable` is not abstract in `IterableOps`: it delegates to an -`iterableFactory` member (which is abstract): +Actually, the `from` operation is not defined directly in `IterableOps` but is accessed via +an (abstract) `iterableFactory` member: ~~~ scala trait IterableOps[+A, +CC[_], +C] { - protected def fromIterable[E](it: Iterable[E]): CC[E] = - iterableFactory.from(it) - def iterableFactory: IterableFactory[CC] + + def map[B](f: A => B): CC[B] = + iterableFactory.from(new View.Map(this, f)) } ~~~ @@ -336,12 +336,9 @@ trait MapOps[K, +V, +CC[_, _], +C] extends IterableOps[(K, V), Iterable, C] { def map[K2, V2](f: ((K, V)) => (K2, V2)): CC[K2, V2] = - mapFromIterable(new View.Map(this, f)) - - // Similar to fromIterable, but returns a Map collection type - protected def mapFromIterable[K2, V2](it: Iterable[(K2, V2)]): CC[K2, V2] = - mapFactory.from(it) + mapFactory.from(new View.Map(this, f)) + // Similar to iterableFactory, but for Map collection types def mapFactory: MapFactory[CC] } @@ -387,7 +384,7 @@ type of elements. The following code shows the relevant parts of `IterableOps` a ~~~ scala trait IterableOps[+A, +CC[_], +C] { def iterableFactory: IterableFactory[CC] - protected def fromSpecificIterable(coll: Iterable[A]): C + protected def fromSpecific(coll: IterableOnce[A]): C protected def newSpecificBuilder: Builder[A, C] } diff --git a/_overviews/core/custom-collection-operations.md b/_overviews/core/custom-collection-operations.md index 29b3e9dd77..87b2f863ae 100644 --- a/_overviews/core/custom-collection-operations.md +++ b/_overviews/core/custom-collection-operations.md @@ -279,7 +279,7 @@ trait BuildFrom[-From, -A, +C] { /** @return a collection of type `C` containing the same elements * (of type `A`) as the source collection `it`. */ - def fromSpecificIterable(from: From)(it: Iterable[A]): C + def fromSpecific(from: From)(it: IterableOnce[A]): C /** @return a Builder for the collection type `C`, containing * elements of type `A`. diff --git a/_overviews/core/custom-collections.md b/_overviews/core/custom-collections.md index b73685ee68..d673110cea 100644 --- a/_overviews/core/custom-collections.md +++ b/_overviews/core/custom-collections.md @@ -72,6 +72,8 @@ class Capped1[A] private (val capacity: Int, val length: Int, offset: Int, elems elem } } + + override def className = "Capped1" } ~~~ @@ -101,6 +103,9 @@ to implement `iterator` to make the generic collection operations (such as `foldLeft`, `count`, etc.) work on `Capped` collections. Here we implement it by using indexed access. +Last, we override `className` to return the name of the collection, +“Capped1”. This name is used by the `toString` operation. + Here are some interactions with the `Capped1` collection: ~~~ scala @@ -165,7 +170,11 @@ class Capped2[A] private (val capacity: Int, val length: Int, offset: Int, elems def iterator: Iterator[A] = // as before + override def className = "Capped2" override val iterableFactory: IterableFactory[Capped2] = new Capped2Factory(capacity) + override protected def fromSpecific(coll: IterableOnce[A]): Capped2[A] = iterableFactory.from(coll) + override protected def newSpecificBuilder: mutable.Builder[A, Capped2[A]] = iterableFactory.newBuilder + override def empty: Capped2[A] = iterableFactory.empty } @@ -199,14 +208,22 @@ type of methods like `map`, `flatMap` or `concat` is defined by the second type parameter passed to class `IterableOps`, i.e., in class `Capped2`, it is `Capped2` itself. -To construct a `Capped2`, the `fromSpecificIterable` and -`newSpecificBuilder` implementations inherited from `immutable.Iterable` -delegate to the `iterableFactory` member, which is overridden here to -return an instance of `Capped2Factory`. This class -provides convenient factory methods to build collections. Eventually, -these methods delegate to `empty`, which builds an empty `Capped2` -instance, and `newBuilder`, which uses the `appended` operation -to grow a `Capped2` collection. +Operations returning `Capped2[A]` collections are implemented in `IterableOps` +in terms of the `fromSpecific` and `newSpecificBuilder` operations. The +`immutable.Iterable[A]` parent class implements the `fromSpecific` and +`newSpecificBuilder` such that they only return `immutable.Iterable[A]` +collections instead of the expected `Capped2[A]` collections. Consequently, +we override the `fromSpecific` and `newSpecificBuilder` operations to +make them return a `Capped2[A]` collection. Another inherited operation +returning a too general type is `empty`. We override it to return a +`Capped2[A]` collection too. All these overrides simply forward to the +collection factory referred to by the `iterableFactory` member, whose value +is an instance of class `Capped2Factory`. + +The `Capped2Factory` class provides convenient factory methods to build +collections. Eventually, these methods delegate to the `empty` operation, +which builds an empty `Capped2` instance, and `newBuilder`, which uses the +`appended` operation to grow a `Capped2` collection. With the refined implementation of the [`Capped2` class](#second-version-of-capped-class), the transformation operations work now as expected, and the @@ -233,9 +250,15 @@ res4: Capped2[Int] = Capped2(2, 3, 4, 5) ~~~ This implementation now behaves correctly, but we can still improve -a few things. Since our collection is strict, we can take advantage -of the better performance offered by -strict implementations of transformation operations. +a few things: + +- since our collection is strict, we can take advantage + of the better performance offered by + strict implementations of transformation operations, +- since our `fromSpecific`, `newSpecificBuilder` and `empty` + operation just forward to the `iterableFactory` member, + we can use the `IterableFactoryDefaults` trait that provides + such implementations. ### Final version of `Capped` class ### @@ -245,6 +268,7 @@ import scala.collection._ final class Capped[A] private (val capacity: Int, val length: Int, offset: Int, elems: Array[Any]) extends immutable.Iterable[A] with IterableOps[A, Capped, Capped[A]] + with IterableFactoryDefaults[A, Capped] with StrictOptimizedIterableOps[A, Capped, Capped[A]] { self => def this(capacity: Int) = @@ -277,6 +301,8 @@ final class Capped[A] private (val capacity: Int, val length: Int, offset: Int, override def knownSize: Int = length + override def className = "Capped" + override val iterableFactory: IterableFactory[Capped] = new CappedFactory(capacity) } @@ -303,6 +329,9 @@ That is it. The final [`Capped` class](#final-version-of-capped-class): - extends the `StrictOptimizedIterableOps` trait, which overrides all transformation operations to take advantage of strict builders, +- extends the `IterableFactoryDefaults` trait, which overrides the + `fromSpecific`, `newSpecificBuilder` and `empty` operations to forward + to the `iterableFactory`, - overrides a few operations for performance: the `view` now uses indexed access, and the `iterator` delegates to the view. The `knownSize` operation is also overridden because the size is always @@ -371,10 +400,12 @@ representation. Base.fromInt(groups(idx / N) >> (idx % N * S) & M) } - override protected def fromSpecificIterable(coll: Iterable[Base]): RNA1 = - fromSeq(coll.toSeq) + override protected def fromSpecific(coll: IterableOnce[Base]): RNA1 = + fromSeq(coll.iterator.toSeq) override protected def newSpecificBuilder: mutable.Builder[Base, RNA1] = iterableFactory.newBuilder[Base].mapResult(fromSeq) + override def empty: RNA1 = fromSeq(Seq.empty) + override def className = "RNA1" } object RNA1 { @@ -422,7 +453,7 @@ abstract methods: We also override the following members used by transformation operations such as `filter` and `take`: -- `fromSpecificIterable`, implemented by the `fromSeq` method of the `RNA1` +- `fromSpecific`, implemented by the `fromSeq` method of the `RNA1` companion object, - `newSpecificBuilder`, implemented by using the default `IndexedSeq` builder and transforming its result into an `RNA1` with the `mapResult` method. @@ -554,26 +585,28 @@ this is why we always get a `Vector` as a result. import RNA2._ def apply(idx: Int): Base = // as before - override protected def fromSpecificIterable(coll: Iterable[Base]): RNA2 = // as before + override protected def fromSpecific(coll: IterableOnce[Base]): RNA2 = // as before override protected def newSpecificBuilder: mutable.Builder[Base, RNA2] = // as before // Overloading of `appended`, `prepended`, `appendedAll`, // `prependedAll`, `map`, `flatMap` and `concat` to return an `RNA2` // when possible + def concat(suffix: IterableOnce[Base]): RNA2 = + fromSpecific(iterator ++ suffix.iterator) + // symbolic alias for `concat` + @inline final def ++ (suffix: IterableOnce[Base]): RNA2 = concat(suffix) def appended(base: Base): RNA2 = - fromSpecificIterable(new View.Append(this, base)) - def appendedAll(suffix: Iterable[Base]): RNA2 = - fromSpecificIterable(new View.Concat(this, suffix)) + fromSpecific(new View.Append(this, base)) + def appendedAll(suffix: IterableOnce[Base]): RNA2 = + concat(suffix) def prepended(base: Base): RNA2 = - fromSpecificIterable(new View.Prepend(base, this)) - def prependedAll(prefix: Iterable[Base]): RNA2 = - fromSpecificIterable(new View.Concat(prefix, this)) + fromSpecific(new View.Prepend(base, this)) + def prependedAll(prefix: IterableOnce[Base]): RNA2 = + fromSpecific(prefix.iterator ++ iterator) def map(f: Base => Base): RNA2 = - fromSpecificIterable(new View.Map(this, f)) + fromSpecific(new View.Map(this, f)) def flatMap(f: Base => IterableOnce[Base]): RNA2 = - fromSpecificIterable(new View.FlatMap(this, f)) - def concat(suffix: Iterable[Base]): RNA2 = - fromSpecificIterable(new View.Concat(this, suffix)) + fromSpecific(new View.FlatMap(this, f)) } To address this shortcoming, you need to overload the methods that @@ -581,7 +614,7 @@ return an `IndexedSeq[B]` for the case where `B` is known to be `Base`, to return an `RNA2` instead. Compared to [class `RNA1`](#first-version-of-rna-strands-class) -we added overloads for methods `appended`, `appendedAll`, `prepended`, +we added overloads for methods `concat`, `appended`, `appendedAll`, `prepended`, `prependedAll`, `map` and `flatMap`. This implementation now behaves correctly, but we can still improve a few things. Since our @@ -622,43 +655,31 @@ final class RNA private ( Base.fromInt(groups(idx / N) >> (idx % N * S) & M) } - // Mandatory implementation of `fromSpecificIterable` and - // `newSpecificBuilder`, from `IterableOps` - override protected def fromSpecificIterable(coll: Iterable[Base]): RNA = + // Mandatory overrides of `fromSpecific`, `newSpecificBuilder`, + // and `empty`, from `IterableOps` + override protected def fromSpecific(coll: IterableOnce[Base]): RNA = RNA.fromSpecific(coll) override protected def newSpecificBuilder: mutable.Builder[Base, RNA] = RNA.newBuilder + override def empty: RNA = RNA.empty // Overloading of `appended`, `prepended`, `appendedAll`, `prependedAll`, // `map`, `flatMap` and `concat` to return an `RNA` when possible + def concat(suffix: IterableOnce[Base]): RNA = + strictOptimizedConcat(suffix, newSpecificBuilder) + @inline final def ++ (suffix: IterableOnce[Base]): RNA = concat(suffix) def appended(base: Base): RNA = (newSpecificBuilder ++= this += base).result() def appendedAll(suffix: Iterable[Base]): RNA = - (newSpecificBuilder ++= this ++= suffix).result() + strictOptimizedConcat(suffix, newSpecificBuilder) def prepended(base: Base): RNA = (newSpecificBuilder += base ++= this).result() def prependedAll(prefix: Iterable[Base]): RNA = (newSpecificBuilder ++= prefix ++= this).result() - def map(f: Base => Base): RNA = { - var b = newSpecificBuilder - for (base <- this) { - b += f(base) - } - b.result() - } - def flatMap(f: Base => IterableOnce[Base]): RNA = { - var b = newSpecificBuilder - for (base <- this) { - b ++= f(base) - } - b.result() - } - def concat(suffix: IterableOnce[Base]): RNA = { - val b = newSpecificBuilder - b ++= this - b ++= suffix - b.result() - } + def map(f: Base => Base): RNA = + strictOptimizedMap(newSpecificBuilder, f) + def flatMap(f: Base => IterableOnce[Base]): RNA = + strictOptimizedFlatMap(newSpecificBuilder, f) // Optional re-implementation of iterator, // to make it more efficient. @@ -673,6 +694,7 @@ final class RNA private ( } } + override def className = "RNA" } object RNA extends SpecificIterableFactory[Base, RNA] { @@ -706,12 +728,13 @@ The final [`RNA` class](#final-version-of-rna-strands-class): - extends the `StrictOptimizedSeqOps` trait, which overrides all transformation operations to take advantage of strict builders, -- uses a strict mode for overloads of transformation operations that return - an `RNA`, +- uses utility operations provided by the `StrictOptimizedSeqOps` trait such as + `strictOptimizedConcat` to implement overload of transformation operations that + return an `RNA` collection, - has a companion object that extends `SpecificIterableFactory[Base, RNA]`, which makes it possible to use it as a parameter of a `to` call (to convert any collection of bases to an `RNA`, e.g. `List(U, A, G, C).to(RNA)`), -- moves the `newSpecificBuilder` and `fromSpecificIterable` implementations +- moves the `newSpecificBuilder` and `fromSpecific` implementations to the companion object. The discussion so far centered on the minimal amount of definitions @@ -826,35 +849,23 @@ class PrefixMap[A] } // Overloading of transformation methods that should return a PrefixMap - def map[B](f: ((String, A)) => (String, B)): PrefixMap[B] = { - val b = PrefixMap.newBuilder[B] - for (kv <- this) { - b += f(kv) - } - b.result() - } - def flatMap[B](f: ((String, A)) => IterableOnce[(String, B)]): PrefixMap[B] = { - val b = PrefixMap.newBuilder[B] - for (kv <- this) { - b ++= f(kv) - } - b.result() - } + def map[B](f: ((String, A)) => (String, B)): PrefixMap[B] = + strictOptimizedMap(PrefixMap.newBuilder, f) + def flatMap[B](f: ((String, A)) => IterableOnce[(String, B)]): PrefixMap[B] = + strictOptimizedFlatMap(PrefixMap.newBuilder, f) // Override `concat` and `empty` methods to refine their return type - override def concat[B >: A](suffix: Iterable[(String, B)]): PrefixMap[B] = { - val b = PrefixMap.newBuilder[B] - b ++= this - b ++= suffix - b.result() - } + override def concat[B >: A](suffix: IterableOnce[(String, B)]): PrefixMap[B] = + strictOptimizedConcat(suffix, PrefixMap.newBuilder) override def empty: PrefixMap[A] = new PrefixMap // Members declared in scala.collection.mutable.Clearable - def clear(): Unit = suffixes = immutable.Map.empty + override def clear(): Unit = suffixes = immutable.Map.empty // Members declared in scala.collection.IterableOps - override protected def fromSpecificIterable(coll: Iterable[(String, A)]): PrefixMap[A] = PrefixMap.from(coll) + override protected def fromSpecific(coll: IterableOnce[(String, A)]): PrefixMap[A] = PrefixMap.from(coll) override protected def newSpecificBuilder: mutable.Builder[(String, A), PrefixMap[A]] = PrefixMap.newBuilder + + override def className = "PrefixMap" } object PrefixMap { @@ -871,6 +882,8 @@ object PrefixMap { def newBuilder[A]: mutable.Builder[(String, A), PrefixMap[A]] = new mutable.GrowableBuilder[(String, A), PrefixMap[A]](empty) + import scala.language.implicitConversions + implicit def toFactory[A](self: this.type): Factory[(String, A), PrefixMap[A]] = new Factory[(String, A), PrefixMap[A]] { def fromSpecific(it: IterableOnce[(String, A)]): PrefixMap[A] = self.from(it) @@ -953,8 +966,7 @@ exactly one element `x`, if the option value is `Some(x)`. However, in all these cases, to build the right kind of collection you need to start with an empty collection of that kind. This is -provided by the `empty` method, which is the last method defined in -`PrefixMap`. This method simply returns a fresh `PrefixMap`. +provided by the `empty` method, which simply returns a fresh `PrefixMap`. We'll now turn to the companion object `PrefixMap`. In fact it is not strictly necessary to define this companion object, as class `PrefixMap` From e6c3ab621a841d3ec0d2f96fa7ced062c5a8563d Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Tue, 9 Apr 2019 13:40:10 +0200 Subject: [PATCH 0449/3075] Credit book Programming in Scala --- _overviews/core/architecture-of-scala-213-collections.md | 7 +++++++ _overviews/core/custom-collections.md | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/_overviews/core/architecture-of-scala-213-collections.md b/_overviews/core/architecture-of-scala-213-collections.md index 557c8c0258..ad4fede7b7 100644 --- a/_overviews/core/architecture-of-scala-213-collections.md +++ b/_overviews/core/architecture-of-scala-213-collections.md @@ -425,3 +425,10 @@ This document explains that: You now have all the required knowledge to implement [custom collection types]({{ site.baseurl }}/overviews/core/custom-collections.html). + +### Acknowledgement ### + +This page contains material adapted from the book +[Programming in Scala](http://www.artima.com/shop/programming_in_scala) by +Odersky, Spoon and Venners. We thank Artima for graciously agreeing to its +publication. diff --git a/_overviews/core/custom-collections.md b/_overviews/core/custom-collections.md index d673110cea..65941555ce 100644 --- a/_overviews/core/custom-collections.md +++ b/_overviews/core/custom-collections.md @@ -1010,7 +1010,7 @@ methods without having to reimplement them all over again. ### Acknowledgement ### -These pages contain material adapted from the 2nd edition of +This page contains material adapted from the book [Programming in Scala](http://www.artima.com/shop/programming_in_scala) by Odersky, Spoon and Venners. We thank Artima for graciously agreeing to its publication. From cfa0b2f9be2286f4c1c9bff29649819d8a275883 Mon Sep 17 00:00:00 2001 From: matko-CT Date: Wed, 10 Apr 2019 11:02:19 +0200 Subject: [PATCH 0450/3075] typo underly to underlie --- _overviews/collections/concrete-immutable-collection-classes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/collections/concrete-immutable-collection-classes.md b/_overviews/collections/concrete-immutable-collection-classes.md index 78ca9d0857..64bfb62655 100644 --- a/_overviews/collections/concrete-immutable-collection-classes.md +++ b/_overviews/collections/concrete-immutable-collection-classes.md @@ -152,7 +152,7 @@ Ranges are represented in constant space, because they can be defined by just th Hash tries are a standard way to implement immutable sets and maps efficiently. They are supported by class [immutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/HashMap.html). Their representation is similar to vectors in that they are also trees where every node has 32 elements or 32 subtrees. But the selection of these keys is now done based on hash code. For instance, to find a given key in a map, one first takes the hash code of the key. Then, the lowest 5 bits of the hash code are used to select the first subtree, followed by the next 5 bits and so on. The selection stops once all elements stored in a node have hash codes that differ from each other in the bits that are selected up to this level. -Hash tries strike a nice balance between reasonably fast lookups and reasonably efficient functional insertions (`+`) and deletions (`-`). That's why they underly Scala's default implementations of immutable maps and sets. In fact, Scala has a further optimization for immutable sets and maps that contain less than five elements. Sets and maps with one to four elements are stored as single objects that just contain the elements (or key/value pairs in the case of a map) as fields. The empty immutable set and the empty immutable map is in each case a single object - there's no need to duplicate storage for those because an empty immutable set or map will always stay empty. +Hash tries strike a nice balance between reasonably fast lookups and reasonably efficient functional insertions (`+`) and deletions (`-`). That's why they underlie Scala's default implementations of immutable maps and sets. In fact, Scala has a further optimization for immutable sets and maps that contain less than five elements. Sets and maps with one to four elements are stored as single objects that just contain the elements (or key/value pairs in the case of a map) as fields. The empty immutable set and the empty immutable map is in each case a single object - there's no need to duplicate storage for those because an empty immutable set or map will always stay empty. ## Red-Black Trees From 905395328bfe249feaef59f74950dc462af448f1 Mon Sep 17 00:00:00 2001 From: fmc Date: Wed, 10 Apr 2019 16:36:45 -0400 Subject: [PATCH 0451/3075] [chore] Fix some spelling and grammar errors --- _overviews/macros/typeproviders.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_overviews/macros/typeproviders.md b/_overviews/macros/typeproviders.md index db886a9c4b..f6fb1615b3 100644 --- a/_overviews/macros/typeproviders.md +++ b/_overviews/macros/typeproviders.md @@ -35,7 +35,7 @@ concrete examples. Slides and accompanying code can be found at [https://github. ## Introduction Type providers are a strongly-typed type-bridging mechanism, which enables information-rich programming in F# 3.0. -A type provider is a compile-time facility, which is capable of generating definitions and their implementations +A type provider is a compile-time facility which is capable of generating definitions and their implementations based on static parameters describing datasources. Type providers can operate in two modes: non-erased and erased. The former is similar to textual code generation in the sense that every generated type becomes bytecode, while in the latter case generated types only manifest themselves during type checking, but before bytecode generation @@ -70,7 +70,7 @@ takes a connection string and generates a module that encapsulates the given dat new Db {} } -It is true that noone outside the macro expansion block would be able to refer to the `Coffee` class directly, +It is true that no one outside the macro expansion block would be able to refer to the `Coffee` class directly, however if we inspect the type of `db`, we will find something fascinating. scala> val db = h2db("jdbc:h2:coffees.h2.db") From 1077b0ac26a89b64deaa6121ff30869933c7da84 Mon Sep 17 00:00:00 2001 From: Kshitij Date: Sun, 14 Apr 2019 18:16:19 +0530 Subject: [PATCH 0452/3075] Fix reverseSort to first sort and then reverse --- _overviews/FAQ/finding-implicits.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/FAQ/finding-implicits.md b/_overviews/FAQ/finding-implicits.md index c12d7b2748..015216f28c 100644 --- a/_overviews/FAQ/finding-implicits.md +++ b/_overviews/FAQ/finding-implicits.md @@ -124,7 +124,7 @@ Context bounds are more useful when you just need to _pass_ them to other methods that use them. For example, the method `sorted` on `Seq` needs an implicit `Ordering`. To create a method `reverseSort`, one could write: - def reverseSort[T : Ordering](seq: Seq[T]) = seq.reverse.sorted + def reverseSort[T : Ordering](seq: Seq[T]) = seq.sorted.reverse Because `Ordering[T]` was implicitly passed to `reverseSort`, it can then pass it implicitly to `sorted`. From 6307ea383f3122ce8faccd65434b60d38598885c Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Tue, 16 Apr 2019 13:56:53 -0700 Subject: [PATCH 0453/3075] JDK 12 is out --- _overviews/jdk-compatibility/overview.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_overviews/jdk-compatibility/overview.md b/_overviews/jdk-compatibility/overview.md index 477a039c86..b776a87a6b 100644 --- a/_overviews/jdk-compatibility/overview.md +++ b/_overviews/jdk-compatibility/overview.md @@ -56,9 +56,9 @@ To help with testing on JDK 11, see [scala/scala-dev#559](https://github.com/sca ## JDK 12 compatibility notes -As of February 2019, JDK 12 is not in full release, but early-access builds are available. Note that even the final JDK 12 release will not be an LTS release, so the remarks above about non-LTS releases apply. +JDK 12 was released in March 2019. But it is not an LTS release, so the remarks above about non-LTS releases apply. -Scala has not yet been extensively tested on JDK 12. +Scala has not been extensively tested on JDK 12. However, the Scala 2.12 community build is [up and running](https://scala-ci.typesafe.com/view/scala-2.12.x/job/scala-2.12.x-jdk12-integrate-community-build/) on an early-access JDK 12 build, and most projects are green. @@ -67,7 +67,7 @@ Two significant known issues with Scala 2.12.8 on JDK 12 are: * the `-release` flag doesn't work ([scala/bug#11403](https://github.com/scala/bug/issues/11403)) * the optimizer doesn't work ([scala/bug#11372](https://github.com/scala/bug/issues/11372)) -Both issues have already been fixed. The fixes will be included in [Scala 2.12.9](https://github.com/scala/scala/milestone/77). A release date for 2.12.9 has not been set. In the meantime, consider using a [Scala nightly build](https://stackoverflow.com/questions/40622878/how-do-i-tell-sbt-to-use-a-nightly-build-of-scala-2-12-or-2-13) to test the fixes. +Both issues have already been fixed. The fixes will be included in [Scala 2.12.9](https://github.com/scala/scala/milestone/77). 2.12.9 is tentatively planned for release in June 2019. In the meantime, consider using a [Scala nightly build](https://stackoverflow.com/questions/40622878/how-do-i-tell-sbt-to-use-a-nightly-build-of-scala-2-12-or-2-13) to test the fixes. In other respects, so far it appears that 12 is similar to 11 with respect to Scala compatibility. From ff6580c6247ee091b4805335a67480f2153c3bec Mon Sep 17 00:00:00 2001 From: Bert Kellerman Date: Thu, 18 Apr 2019 08:49:07 -0700 Subject: [PATCH 0454/3075] Update pattern-matching.md --- _tour/pattern-matching.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_tour/pattern-matching.md b/_tour/pattern-matching.md index 5a6d4969c4..b5f9e37d46 100644 --- a/_tour/pattern-matching.md +++ b/_tour/pattern-matching.md @@ -65,8 +65,8 @@ case class VoiceRecording(contactName: String, link: String) extends Notificatio ``` def showNotification(notification: Notification): String = { notification match { - case Email(email, title, _) => - s"You got an email from $email with title: $title" + case Email(sender, title, _) => + s"You got an email from $sender with title: $title" case SMS(number, message) => s"You got an SMS from $number! Message: $message" case VoiceRecording(name, link) => @@ -80,7 +80,7 @@ println(showNotification(someSms)) // prints You got an SMS from 12345! Message println(showNotification(someVoiceRecording)) // you received a Voice Recording from Tom! Click the link to hear it: voicerecording.org/id/123 ``` -The function `showNotification` takes as a parameter the abstract type `Notification` and matches on the type of `Notification` (i.e. it figures out whether it's an `Email`, `SMS`, or `VoiceRecording`). In the `case Email(email, title, _)` the fields `email` and `title` are used in the return value but the `body` field is ignored with `_`. +The function `showNotification` takes as a parameter the abstract type `Notification` and matches on the type of `Notification` (i.e. it figures out whether it's an `Email`, `SMS`, or `VoiceRecording`). In the `case Email(sender, title, _)` the fields `sender` and `title` are used in the return value but the `body` field is ignored with `_`. ## Pattern guards Pattern guards are simply boolean expressions which are used to make cases more specific. Just add `if ` after the pattern. @@ -88,7 +88,7 @@ Pattern guards are simply boolean expressions which are used to make cases more def showImportantNotification(notification: Notification, importantPeopleInfo: Seq[String]): String = { notification match { - case Email(email, _, _) if importantPeopleInfo.contains(email) => + case Email(sender, _, _) if importantPeopleInfo.contains(sender) => "You got an email from special someone!" case SMS(number, _) if importantPeopleInfo.contains(number) => "You got an SMS from special someone!" @@ -110,7 +110,7 @@ println(showImportantNotification(importantEmail, importantPeopleInfo)) println(showImportantNotification(importantSms, importantPeopleInfo)) ``` -In the `case Email(email, _, _) if importantPeopleInfo.contains(email)`, the pattern is matched only if the `email` is in the list of important people. +In the `case Email(sender, _, _) if importantPeopleInfo.contains(sender)`, the pattern is matched only if the `sender` is in the list of important people. ## Matching on type only You can match on the type like so: From 03df61186b2d78c3fa26cb6482c9f024030593da Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Mon, 22 Apr 2019 19:54:50 -0700 Subject: [PATCH 0455/3075] standardize CoC let's only have the text in one place --- CODE_OF_CONDUCT.md | 81 +++------------------------------------------- 1 file changed, 5 insertions(+), 76 deletions(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 948de8e719..0511f2126d 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,78 +1,7 @@ -## Scala Code of Conduct +all repositories in these organizations: -We are committed to providing a friendly, safe and welcoming environment for -all, regardless of level of experience, gender, gender identity and expression, -sexual orientation, disability, personal appearance, body size, race, ethnicity, -age, religion, nationality, or other such characteristics. +* [scala](https://github.com/scala) +* [scalacenter](https://github.com/scalacenter) +* [lampepfl](https://github.com/lampepfl) -### Our Standards - -**Whether you’re a regular contributor or a newcomer, we care about making this community a welcoming and safe place for you and we’ve got your back.** - -As a member of the community, you agree to the following: - -**Encouraged:** - -- Be kind and courteous. -- Respect differences of opinion and remember that every design or implementation choice carries a trade-off and numerous costs. There is seldom a single right answer. -- Remember that everyone was new to Scala at some point. We want to encourage newcomers to join our community and learn the Scala language and ecosystem. Assume competence. -- Show empathy towards other community members. - -**Discouraged:** - -- Keep unstructured critique to a minimum. We encourage sharing ideas and perspectives, so please ensure that your feedback is constructive and relevant. If you have solid ideas you want to experiment with, make a fork and see how it works. -- Avoid aggressive and micro-aggressive behavior, such as unconstructive criticism, providing corrections that do not improve the conversation (sometimes referred to as "well actually"s), repeatedly interrupting or talking over someone else, feigning surprise at someone’s lack of knowledge or awareness about a topic, or subtle prejudice (for example, comments like “That’s so easy my grandmother could do it.”). For more examples of this kind of behavior, [see the Recurse Center's user manual](https://www.recurse.com/manual#sec-environment). -- We will exclude you from interaction if you insult, demean or harass anyone. The term “Harassment” includes “Unacceptable Behavior” described in the [Citizen Code of Conduct](http://citizencodeofconduct.org/). **In particular, we don’t tolerate behavior that excludes people in socially marginalized groups.** -- Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member's behavior, please contact one of the [moderators](https://contributors.scala-lang.org/about) or any member of the [Scala Center](http://scala.epfl.ch/) immediately. -- Likewise any spamming, trolling, flaming, baiting or other attention-stealing behaviour is not welcome. - -### Moderation - -These are the policies for upholding our community’s standards of conduct. If -you feel that a thread needs moderation, please contact anyone on the -[moderation team](https://contributors.scala-lang.org/about), or any employee of -the [Scala Center](https://scala.epfl.ch/). - -- Remarks that violate the above code of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.) -- Moderators will warn users who make remarks inconsistent with the above code of conduct. -- If the warning is unheeded, the user will be “kicked,” i.e., kicked out of the communication channel to cool off. -- If the user comes back and continues to make trouble, they will be banned, i.e., indefinitely excluded. -- Moderators may choose at their discretion to un-ban the user if it was a first offense and they if they make suitable amends with the offended party. -- If you think a ban is unjustified, please take it up with that moderator, or with a different moderator, in private. Complaints about bans in-channel are not allowed. -- Moderators are held to a higher standard than other community members. If a moderator acts inappropriately, they should expect less leeway than others. - -In the Scala community we strive to go the extra step to look out for each -other. Don’t just aim to be technically unimpeachable; try to be your best self. -In particular, avoid exacerbating offensive or sensitive issues, particularly if -they’re off-topic; this all too often leads to unnecessary fights, hurt -feelings, and damaged trust; worse, it can drive people away from the community -entirely. - -If someone takes issue with something you said or did, resist the urge to be -defensive. Rather, stop the offending behavior, apologize, and be sensitive -thereafter. Even if you feel you were misinterpreted or unfairly accused, -chances are good there was something you could’ve communicated better — remember -that it’s your responsibility to make your fellow Scala developers comfortable. -We are all here first and foremost because we want to talk about cool -technology, and everyone wants to get along in doing so. People are generally -eager to assume good intent and forgive. - -### Domain - -The enforcement policies listed above apply to all official Scala channels: -mailing lists, GitHub repositories and Gitter channels under scala and -scalacenter, Discourse, and Scala Center venues and hackathons. For other -projects adopting the Scala Code of Conduct, please contact the maintainers of -those projects for enforcement. If you wish to use this code of conduct for your -own project, consider explicitly mentioning your moderation policy or making a -copy with your own moderation policy so as to avoid confusion. - -### Credits - -Adapted from and/or inspired by multiple successful Codes of Conduct, including: - -* [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html) -* [The Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling) -* [The Contributor Covenant v1.4.0](http://contributor-covenant.org/version/1/4/) -* [The Recurse Center's User Manual](https://www.recurse.com/manual#sec-environment) -* [The 18F Code of Conduct](https://18f.gsa.gov/code-of-conduct/) \ No newline at end of file +are covered by the Scala Code of Conduct: https://scala-lang.org/conduct/ From e1156e6a824aa59a127e02b12ad09705b069a43e Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Fri, 26 Apr 2019 11:23:17 +0200 Subject: [PATCH 0456/3075] Copy the strawman FAQ to collections-migration-213 --- _data/overviews.yml | 5 + _overviews/core/collections-migration-213.md | 330 +++++++++++++++++++ 2 files changed, 335 insertions(+) create mode 100644 _overviews/core/collections-migration-213.md diff --git a/_data/overviews.yml b/_data/overviews.yml index 8318194013..0b5470023e 100644 --- a/_data/overviews.yml +++ b/_data/overviews.yml @@ -82,6 +82,11 @@ url: "collections-2.13/creating-collections-from-scratch.html" - title: Conversions Between Java and Scala Collections url: "collections-2.13/conversions-between-java-and-scala-collections.html" + - title: Migrating a Project to Scala 2.13's Collections + icon: sitemap + url: "core/collections-migration-213.html" + description: "This page describes the main changes for collection users that migrate to Scala + 2.13 and shows how to cross-build projects with Scala 2.11 / 2.12 and 2.13." - title: The Architecture of Scala 2.13’s Collections icon: sitemap url: "core/architecture-of-scala-213-collections.html" diff --git a/_overviews/core/collections-migration-213.md b/_overviews/core/collections-migration-213.md new file mode 100644 index 0000000000..64ad70dc07 --- /dev/null +++ b/_overviews/core/collections-migration-213.md @@ -0,0 +1,330 @@ +--- +layout: singlepage-overview +title: Migrating a Project to Scala 2.13's Collections +permalink: /overviews/core/:title.html +--- + +This document describes the main changes for collection users that migrate to Scala 2.13 and shows +how to cross-build projects with Scala 2.11 / 2.12 and 2.13. + +For an in-depth overview of the Scala 2.13 collections library, see the [collections guide]({{ site.baseurl }}/overviews/collections-2.13/introduction.html). The implementation details of the 2.13 collections are explained in the document [the architecture of Scala collections]({{ site.baseurl }}/overviews/core/architecture-of-scala-213-collections.html). + +## What are the major changes? + +See the list at the top of the [2.13.0-M4 release notes](https://github.com/scala/scala/releases/tag/v2.13.0-M4). + +## What are the breaking changes? + +The following table summarizes the breaking changes: + +| Description | Old Code | New Code | Automatic Migration Rule | +| ----------- | -------- | -------- | ------------------------ | +| Method `to[C[_]]` has been removed (it might be reintroduced but deprecated, though) | `xs.to[List]` | `xs.to(List)` | `NewCollections`, `CrossCompat` | +| `mutable.Map` no longer have an `updated` method | `mutable.Map(1 -> 2).updated(1, 3)` | `mutable.Map(1 -> 2).clone() += 1 -> 3` | `NewCollections`, `CrossCompat` | +| `mapValues` and `filterKeys` now return a `MapView` instead of a `Map` | `kvs.mapValues(f)` | `kvs.mapValues(f).toMap` | `RoughlyMapValues` | +| `Iterable` no longer has a `sameElements` operation | `xs1.sameElements(xs2)` | `xs1.iterator.sameElements(xs2)` | `NewCollections`, `CrossCompat` | +| `collection.breakOut` no longer exists | `val xs: List[Int] = ys.map(f)(collection.breakOut)` | `val xs = ys.iterator.map(f).to(List)` | `NewCollections` | +| `zip` on `Map[K, V]` now returns an `Iterable` | `map.zip(iterable)` | `map.zip(iterable).toMap` | `Experimental` | +| `ArrayBuilder.make` does not accept parens anymore | `ArrayBuilder.make[Int]()` | `ArrayBuilder.make[Int]` | `NewCollections`, `CrossCompat` | + +The “Automatic Migration Rule” column gives the name of the migration rule that can be used to automatically update old code to the new expected form. See https://github.com/scala/scala-collection-compat/ for more +details on how to use it. + +Some classes have been removed, made private or have no equivalent in the new design: + +- `ArrayStack`, +- `mutable.FlatHashTable`, +- `mutable.HashTable`, +- `History`, +- `Immutable`, +- `IndexedSeqOptimized`, +- `LazyBuilder`, +- `mutable.LinearSeq`, +- `LinkedEntry`, +- `MapBuilder`, +- `Mutable`, +- `MutableList`, +- `Publisher`, +- `ResizableArray`, +- `RevertibleHistory`, +- `SeqForwarder`, +- `SetBuilder`, +- `Sizing`, +- `SliceInterval`, +- `StackBuilder`, +- `StreamView`, +- `Subscriber`, +- `Undoable`, +- `WrappedArrayBuilder`. + +Other notable changes are: + + - `Iterable.partition` invokes `iterator` twice on non-strict collections and assumes it gets two iterators over the same elements. Strict subclasses override `partition` do perform only a single traversal + - `scala.Seq[+A]` is now `scala.collection.immutable.Seq[A]` (this also affects varargs methods). + - Equality between collections is not anymore defined at the level of `Iterable`. It is defined separately in the `Set`, `Seq` and `Map` branches. Another consequence is that `Iterable` does not anymore have a `canEqual` method. + - The new collections makes more use of overloading. You can find more information about the motivation + behind this choice [here](http://scala-lang.org/blog/2017/05/30/tribulations-canbuildfrom.html). For instance, `Map.map` is overloaded: + + scala> Map(1 -> "a").map + def map[B](f: ((Int, String)) => B): scala.collection.immutable.Iterable[B] + def map[K2, V2](f: ((Int, String)) => (K2, V2)): scala.collection.immutable.Map[K2,V2] + + Type inference has been improved so that `Map(1 -> "a").map(x => (x._1 + 1, x._2))` works, the compiler can infer the parameter type for the function literal. However, using a method reference in 2.13.0-M4 (improvement are on the way for 2.13.0) does not work, and an explicit eta-expansion is necessary: + + scala> def f(t: (Int, String)) = (t._1 + 1, t._2) + scala> Map(1 -> "a").map(f) + ^ + error: missing argument list for method f + Unapplied methods are only converted to functions when a function type is expected. + You can make this conversion explicit by writing `f _` or `f(_)` instead of `f`. + scala> Map(1 -> "a").map(f _) + res10: scala.collection.immutable.Map[Int,String] = ChampHashMap(2 -> a) + - `View`s have been completely redesigned and we expect their usage to have a more predictable evaluation model. + You can read more about the new design [here](http://scala-lang.org/blog/2017/11/28/view-based-collections.html). + - `mutable.ArraySeq` (which wraps an `Array[AnyRef]` in 2.12, meaning that primitives were boxed in the array) can now wrap boxed and unboxed arrays. `mutable.ArraySeq` in 2.13 is in fact equivalent to `WrappedArray` in 2.12, there are specialized subclasses for primitive arrays. Note that a `mutable.ArraySeq` can be used either way for primitive arrays (TODO: document how). `WrappedArray` is deprecated. + - There is no “default” `Factory` (previously known as `[A, C] => CanBuildFrom[Nothing, A, C]`): use `Factory[A, Vector[A]]` explicitly instead. + +## Breaking changes with old syntax still supported + +The following table lists the changes that continue to work with a deprecation warning. + +| Description | Old Code | New Code | Automatic Migration Rule | +| ----------- | -------- | -------- | ------------------------ | +| `collection.Set/Map` no longer have `+` and `-` operations | `xs + 1 - 2` | `xs ++ Set(1) -- Set(2)` | `Experimental` | +| `collection.Map` no longer have `--` operation | `map -- keys` | `map.to(immutable.Map) -- keys` | | +| `immutable.Set/Map`: the `+` operation no longer has an overload accepting multiple values | `Set(1) + (2, 3)` | `Set(1) + 2 + 3` | `NewCollections`, `CrossCompat` | +| `mutable.Set/Map` no longer have a `+` operation | `mutable.Set(1) + 2` | `mutable.Set(1).clone() += 2` | `NewCollections`, `CrossCompat` | +| `SortedSet`: the `to`, `until` and `from` methods are now called `rangeTo`, `rangeUntil` and `rangeFrom`, respectively | `xs.until(42)` | `xs.rangeUntil(42)` | | +| `Traversable` and `TraversableOnce` are replaced with `Iterable` and `IterableOnce`, respectively | `def f(xs: Traversable[Int]): Unit` | `def f(xs: Iterable[Int]): Unit` | `NewCollections`, `CrossCompat` | +| `Stream` is replaced with `LazyList` | `Stream.from(1)` | `LazyList.from(1)` | `RoughlyStreamToLazyList` | +| `Seq#union` is replaced with `concat` | `xs.union(ys)` | `xs.concat(ys)` | | +| `Stream#append` is replaced with `lazyAppendAll` | `xs.append(ys)` | `xs.lazyAppendedAll(ys)` | `NewCollections`, `CrossCompat` | +| `IterableOnce#toIterator` is replaced with `IterableOnce#iterator` | `xs.toIterator` | `xs.iterator` | `NewCollections`, `CrossCompat` | +| `copyToBuffer` has been deprecated | `xs.copyToBuffer(buffer)` | `buffer ++= xs` | `NewCollections`, `CrossCompat` | +| `TupleNZipped` has been replaced with `LazyZipN` | `(xs, ys).zipped` | `xs.lazyZip(ys)` | `NewCollections` | +| `retain` has been renamed to `filterInPlace` | `xs.retain(f)` | `xs.filterInPlace(f.tupled)` | `NewCollections` | +| `:/` and `/:` operators have been deprecated | `(xs :\ y)(f)` | `xs.foldRight(y)(f)` | `NewCollections`, `CrossCompat` | +| `companion` operation has been renamed to `iterableFactory` | `xs.companion` | `xs.iterableFactory` | | + +## Deprecated things in 2.12 that have been removed in 2.13 + +- `collection.convert.JavaConversions`. Use `collection.convert.JavaConverters` instead ; +- `collection.mutable.MutableList` (was not deprecated in 2.12 but was considered to be an implementation detail for implementing other collections). Use an `ArrayDeque` instead, or a `List` and a `var` ; +- `collection.immutable.Stack`. Use a `List` instead ; +- `StackProxy`, `MapProxy`, `SetProxy`, `SeqProxy`, etc. No replacement ; +- `SynchronizedMap`, `SynchronizedBuffer`, etc. Use `java.util.concurrent` instead ; + +## Are there new collection types? + +`scala.collection.immutable.ArraySeq` is an immutable sequence backed by an array. It is used to pass varargs parameters. + +The [`scala-collection-contrib`](https://github.com/scala/scala-collection-contrib) module provides decorators enriching the collections with new operations. You can +think of this artifact as an incubator: if we get evidence that these operations should be part of the core, +we might eventually move them. + +The following collections are provided: + +- `MultiSet` (both mutable and immutable) +- `SortedMultiSet` (both mutable and immutable) +- `MultiDict` (both mutable and immutable) +- `SortedMultiDict` (both mutable and immutable) + +## Are there new operations on collections? + +The following new partitioning operations are available: + +~~~ scala +def groupMap[K, B](key: A => K)(f: A => B): Map[K, CC[B]] // (Where `CC` can be `List`, for instance) +def groupMapReduce[K, B](key: A => K)(f: A => B)(g: (B, B) => B): Map[K, B] +~~~ + +`groupMap` is equivalent to `groupBy(key).mapValues(_.map(f))`. + +`groupMapReduce` is equivalent to `groupBy(key).mapValues(_.map(f).reduce(g))`. + +Mutable collections now have transformation operations that modify the collection in place: + +~~~ scala +def mapInPlace(f: A => A): this.type +def flatMapInPlace(f: A => IterableOnce[A]): this.type +def filterInPlace(p: A => Boolean): this.type +def patchInPlace(from: Int, patch: scala.collection.Seq[A], replaced: Int): this.type +~~~ + +Another new operation is `distinctBy`: + +~~~ scala +def distinctBy[B](f: A => B): C // (Where `C` can be `List[Int]`, for instance) +~~~ + +Last, additional operations are provided by the `scala-collection-contrib` module. You can +think of this artifact as an incubator: if we get evidence that these operations should be part of the core, +we might eventually move them. + +The new operations are provided via an implicit enrichment. You need to add the following import to make them +available: + +~~~ scala +import strawman.collection.decorators._ +~~~ + +The following operations are provided: + +- `Seq` + - `intersperse` +- `Map` + - `zipByKey` / `join` / `zipByKeyWith` + - `mergeByKey` / `fullOuterJoin` / `mergeByKeyWith` / `leftOuterJoin` / `rightOuterJoin` + +## Are there new implementations of existing collection types (changes in performance characteristics)? + +The default `Set` and `Map` are backed by a `ChampHashSet` and a `ChampHashMap`, respectively. The performance characteristics are the same but the +operation implementations are faster. These data structures also have a lower memory footprint. + +`mutable.Queue` and `mutable.Stack` now use `mutable.ArrayDeque`. This data structure supports constant time index access, and amortized constant time +insert and remove operations. + +## How do I cross-build my project against Scala 2.12 and Scala 2.13? + +Most usages of collections are compatible and can cross-compile 2.12 and 2.13 (at the cost of some warnings, sometimes). + +If you cannot get your code to cross-compile, there are various solutions: + - You can maintain a separate branch with the changes for 2.13 and publish releases for 2.13 from this branch. + - You can put source files that don't cross-compile in separate directories and configure sbt to assemble the sources according to the Scala version (see also the examples below): + + // Adds a `src/main/scala-2.13+` source directory for Scala 2.13 and newer + // and a `src/main/scala-2.13-` source directory for Scala version older than 2.13 + unmanagedSourceDirectories in Compile += { + val sourceDir = (sourceDirectory in Compile).value + CrossVersion.partialVersion(scalaVersion.value) match { + case Some((2, n)) if n >= 13 => sourceDir / "scala-2.13+" + case _ => sourceDir / "scala-2.13-" + } + } + + - You can use the [`scala-collection-compat`](https://github.com/scala/scala-collection-compat) library, which makes some of 2.13's APIs available to 2.11 and 2.12. This solution does not always work, for example if your library implements custom collection types. + +Note that the `scala-collection-compat` library has not fully stabilized yet. We expect that new, binary incompatible versions of this library will be published (for 2.11, 2.12) until Scala 2.13 is getting close to its final state. Therefore you might want to avoid adding a dependency on that library to your 2.11 / 2.12 artifacts for the time being. + +Examples of libraries that cross-compile with separate source directories: + - https://github.com/scala/scala-parser-combinators/pull/152 + - https://github.com/scala/scala-xml/pull/222 + - Some other examples are listed here: https://github.com/scala/community-builds/issues/710 + +# Collection Implementers + +## `CanBuildFrom` no longer exists - what were its uses and how can they be replaced? + +`CanBuildFrom` was used to: + - generically implement transformation operations whose return type could + vary according to the type of collection elements (ie mapping a `Char` to a `Char` in a `String` + returns a `String`, but mapping a `Char` to an `Int` returns a `IndexedSeq[Int]`), + - abstract over the arity of collection type constructors (ie `List[_]` vs `Map[_, _]`), + - abstract over implicit parameters required to perform a transformation operations (ie mapping an `A` to a `B` in `SortedSet[A]` + requires an implicit `Ordering[B]` to return a `SortedSet[B]`), + - provide type-driven builders to implement generic transformation methods (eg `Future.traverse`). + +The first three points are now handled using overloading. This means that `Map[K, V]` has two overloads of `map`, +one that takes a `(K, V) => (K', V')` mapping function and returns a `Map[K', V']`, and one that takes a +`(K, V) => A` mapping function and returns an `Iterable[A]`. + +You can find more information about the design [here](http://scala-lang.org/blog/2017/05/30/tribulations-canbuildfrom.html). + +To address the last point, there is a `BuildFrom` typeclass that works exactly like the former `CanBuildFrom`. See the next section +for examples of use. + +## How can I write generic extension methods? + +Depending on the level of desired genericity, several solutions can apply, with different complexity. + +### Write an operation that can consume any collection + +Take an `IterableOnce[A]` as parameter, or an `Iterable[A]` if you need more than one +traversals: + +~~~ scala +implicit class SumByOperation[A](coll: IterableOnce[A]) { + def sumBy[B](f: A => B)(implicit num: Numeric[B]): B = { + val it = coll.iterator + var result = f(it.next()) + while (it.hasNext()) { + result = num.plus(result, it.next()) + } + result + } +} +~~~ + +### Write an operation that returns another collection + +Use `BuildFrom`: + +~~~ scala +def optionSequence[CC[X] <: Iterable[X], A, To](xs: CC[Option[A]])(implicit bf: BuildFrom[CC[Option[A]], A, To]): Option[To] = + xs.foldLeft[Option[Builder[A, To]]](Some(bf.newBuilder(xs))) { + case (Some(builder), Some(a)) => Some(builder += a) + case _ => None + }.map(_.result()) +~~~ + +The `optionSequence` operation can be used on any collection (but not on an `Array` or a `String`): + +~~~ +scala> optionSequence(List[Option[Int]](Some(1), Some(2), Some(3))) +res1: Option[List[Int]] = Some(List(1, 2, 3)) + +scala> optionSequence(Set[Option[(Int, String)]](Some(1 -> "foo"), Some(2 -> "bar")))(TreeMap) // Force the result type +res4: Option[scala.collection.immutable.TreeMap[Int,String]] = Some(TreeMap(1 -> foo, 2 -> bar)) +~~~ + +### Write an operation that can also be applied to a `View`, an `Array` or `String` + +For more advanced cases, or if your operation should also work with `Array`s, `String`s and `View`s, +the pattern given in the previous section is not enough. + +The [`scala-collection-contrib`](https://github.com/scala/scala-collection-contrib) module +provides a more advanced machinery that handles that: + +~~~ scala +class IntersperseOperation[C, S <: HasSeqOps[C]](coll: C)(implicit val seq: S) { + def intersperse[B >: seq.A, That](sep: B)(implicit bf: BuildFrom[C, B, That]): That = + bf.fromSpecificIterable(coll)(new View.Intersperse(seq(coll), sep)) // (Assume that there is a `View.Intersperse` implemented somewhere) +} + +implicit def IntersperseOperation[C](coll: C)(implicit seq: HasSeqOps[C]): SeqDecorator[C, seq.type] = + new IntersperseOperation(coll)(seq) +~~~ + +This pattern makes the `intersperse` operation available to any `Seq` _like_ type (eg. a `SeqView`, an `Array` or a `String`). + +## How do I integrate my collection in the new design? + +See the [online documentation](https://docs.scala-lang.org/overviews/core/custom-collections.html) + +The API of the template traits has changed: +- they used to be suffixed by “Like” (e.g. `SeqLike`), whereas they are now suffixed by “Ops” (e.g. `SeqOps`), +- they used to abstract over the collection type of transformation operations, they now abstract over both + the collection type and the collection type constructor: `SeqLike[+A, +Repr]` has been replaced with + `SeqOps[+A, +CC[_], +C]`. + +## Which methods should I overload to support the “same result type” principle? + +You want to add overloads to specialize a transformation operations such that they return a more specific result. Examples are: +- `map`, on `StringOps`, when the mapping function returns a `Char`, should return a `String` (instead of an `IndexedSeq`), +- `map`, on `Map`, when the mapping function returns a pair, should return a `Map` (instead of an `Iterable`), +- `map`, on `SortedSet`, when an implicit `Ordering` is available for the resulting element type, should return a +`SortedSet` (instead of a `Set`). + +The following table lists transformation operations that might return a too wide type. You might want to overload +these operations to return a more specific type. + + Collection | Operations +---------------|-------------- +`Iterable` | `map`, `flatMap`, `collect`, `scanLeft`, `scanRight`, `groupMap`, `concat`, `zip`, `zipWithIndex`, `zipAll`, `unzip` +`Seq` | `prepended`, `appended`, `prependedAll`, `appendedAll`, `padTo`, `patch` +`immutable.Seq`| `updated` +`SortedSet` | `map`, `flatMap`, `collect`, `zip` +`Map` | `map`, `flatMap`, `collect`, `concat` +`immutable.Map`| `updated`, `transform` +`SortedMap` | `map`, `flatMap`, `collect`, `concat` +`immutable.SortedMap` | `updated` From fb973a8c3c8dd25f2eaf29151a5c6a34b7bbb6c9 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Fri, 26 Apr 2019 11:26:07 +0200 Subject: [PATCH 0457/3075] minor typos --- _overviews/core/collections-migration-213.md | 52 ++++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/_overviews/core/collections-migration-213.md b/_overviews/core/collections-migration-213.md index 64ad70dc07..0e130c677a 100644 --- a/_overviews/core/collections-migration-213.md +++ b/_overviews/core/collections-migration-213.md @@ -27,35 +27,35 @@ The following table summarizes the breaking changes: | `zip` on `Map[K, V]` now returns an `Iterable` | `map.zip(iterable)` | `map.zip(iterable).toMap` | `Experimental` | | `ArrayBuilder.make` does not accept parens anymore | `ArrayBuilder.make[Int]()` | `ArrayBuilder.make[Int]` | `NewCollections`, `CrossCompat` | -The “Automatic Migration Rule” column gives the name of the migration rule that can be used to automatically update old code to the new expected form. See https://github.com/scala/scala-collection-compat/ for more +The “Automatic Migration Rule” column gives the name of the migration rule that can be used to automatically update old code to the new expected form. See [scala-collection-compat](https://github.com/scala/scala-collection-compat) for more details on how to use it. Some classes have been removed, made private or have no equivalent in the new design: -- `ArrayStack`, -- `mutable.FlatHashTable`, -- `mutable.HashTable`, -- `History`, -- `Immutable`, -- `IndexedSeqOptimized`, -- `LazyBuilder`, -- `mutable.LinearSeq`, -- `LinkedEntry`, -- `MapBuilder`, -- `Mutable`, -- `MutableList`, -- `Publisher`, -- `ResizableArray`, -- `RevertibleHistory`, -- `SeqForwarder`, -- `SetBuilder`, -- `Sizing`, -- `SliceInterval`, -- `StackBuilder`, -- `StreamView`, -- `Subscriber`, -- `Undoable`, -- `WrappedArrayBuilder`. +- `ArrayStack` +- `mutable.FlatHashTable` +- `mutable.HashTable` +- `History` +- `Immutable` +- `IndexedSeqOptimized` +- `LazyBuilder` +- `mutable.LinearSeq` +- `LinkedEntry` +- `MapBuilder` +- `Mutable` +- `MutableList` +- `Publisher` +- `ResizableArray` +- `RevertibleHistory` +- `SeqForwarder` +- `SetBuilder` +- `Sizing` +- `SliceInterval` +- `StackBuilder` +- `StreamView` +- `Subscriber` +- `Undoable` +- `WrappedArrayBuilder` Other notable changes are: @@ -299,7 +299,7 @@ This pattern makes the `intersperse` operation available to any `Seq` _like_ typ ## How do I integrate my collection in the new design? -See the [online documentation](https://docs.scala-lang.org/overviews/core/custom-collections.html) +See the [online documentation]({{ site.baseurl }}/overviews/core/custom-collections.html) The API of the template traits has changed: - they used to be suffixed by “Like” (e.g. `SeqLike`), whereas they are now suffixed by “Ops” (e.g. `SeqOps`), From a68cd1b802acf5c1df0f7e9b5cbb78d0223c9ef4 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Mon, 29 Apr 2019 11:59:00 +0200 Subject: [PATCH 0458/3075] review feedback --- _overviews/core/collections-migration-213.md | 188 +++++-------------- 1 file changed, 44 insertions(+), 144 deletions(-) diff --git a/_overviews/core/collections-migration-213.md b/_overviews/core/collections-migration-213.md index 0e130c677a..10bcb21dbf 100644 --- a/_overviews/core/collections-migration-213.md +++ b/_overviews/core/collections-migration-213.md @@ -9,26 +9,39 @@ how to cross-build projects with Scala 2.11 / 2.12 and 2.13. For an in-depth overview of the Scala 2.13 collections library, see the [collections guide]({{ site.baseurl }}/overviews/collections-2.13/introduction.html). The implementation details of the 2.13 collections are explained in the document [the architecture of Scala collections]({{ site.baseurl }}/overviews/core/architecture-of-scala-213-collections.html). -## What are the major changes? - -See the list at the top of the [2.13.0-M4 release notes](https://github.com/scala/scala/releases/tag/v2.13.0-M4). +The most important changes in the Scala 2.13 collections library are: + - Transformation methods no longer have an implicit `CanBuildFrom` parameter. This makes the library easier to understand (in source code, Scaladoc, and IDE code completion). It also makes compiling user code more efficient. + - The type hierarchy is simplified. `Traversable` no longer exists, only `Iterable`. + - The `to[Collection]` method was replaced by the `to(Collection)` method. + - Views have been vastly simplified and work reliably now. They no longer extend their corresponding collection type, for example, an `IndexedSeqView` no longer extends `IndexedSeq`. + - `collection.breakOut` no longer exists, use `.view` and `.to(Collection)` instead. + - Immutable hash sets and hash maps have a new implementation (`ChampHashSet` and `ChampHashMap`, based on the ["CHAMP" encoding](https://michael.steindorfer.name/publications/oopsla15.pdf)). + - New collection types: + - `immutable.ArraySeq` is an effectively immutable sequence that wraps an array + - `immutable.LazyList` is a linked list that is lazy in its state, i.e., whether it's empty or non-empty. This allows creating a `LazyList` without evaluating the `head` element. `immutable.Stream`, which has a strict `head` and a lazy `tail`, is deprecated. + - Deprecated collections were removed (`MutableList`, `immutable.Stack`, others) + - Parallel collections are now in a separate hierarchy in a [separate module](https://github.com/scala/scala-parallel-collections). + - The `scala.jdk.StreamConverters` object provides extension methods to create (sequential or parallel) Java 8 streams for Scala collections. + - `scala.Seq` is now an alias for `scala.collection.immutable.Seq` (no longer `scala.collection.Seq`). Note that this also changes the type of Scala varargs methods. + +## Tools for migrating and cross-building + +The [scala-collection-compat](https://github.com/scala/scala-collection-compat) is a library released for 2.11, 2.12 and 2.13 that provides some of the new APIs from Scala 2.13 for the older versions. This simplifies cross-building projects. + +The module also provides [migratrion rules](https://github.com/scala/scala-collection-compat#migration-tool) for [scalafix](https://scalacenter.github.io/scalafix/docs/users/installation.html) that can update a project's source code to work with the 2.13 collections library. ## What are the breaking changes? -The following table summarizes the breaking changes: +The following table summarizes the breaking changes. The "Automatic Migration Rule" column gives the name of the migration rule that can be used to automatically update old code to the new expected form. | Description | Old Code | New Code | Automatic Migration Rule | | ----------- | -------- | -------- | ------------------------ | -| Method `to[C[_]]` has been removed (it might be reintroduced but deprecated, though) | `xs.to[List]` | `xs.to(List)` | `NewCollections`, `CrossCompat` | -| `mutable.Map` no longer have an `updated` method | `mutable.Map(1 -> 2).updated(1, 3)` | `mutable.Map(1 -> 2).clone() += 1 -> 3` | `NewCollections`, `CrossCompat` | +| Method `to[C[_]]` has been removed (it might be reintroduced but deprecated, though) | `xs.to[List]` | `xs.to(List)` | `Collection213Upgrade`, `Collections213CrossCompat` | | `mapValues` and `filterKeys` now return a `MapView` instead of a `Map` | `kvs.mapValues(f)` | `kvs.mapValues(f).toMap` | `RoughlyMapValues` | -| `Iterable` no longer has a `sameElements` operation | `xs1.sameElements(xs2)` | `xs1.iterator.sameElements(xs2)` | `NewCollections`, `CrossCompat` | -| `collection.breakOut` no longer exists | `val xs: List[Int] = ys.map(f)(collection.breakOut)` | `val xs = ys.iterator.map(f).to(List)` | `NewCollections` | -| `zip` on `Map[K, V]` now returns an `Iterable` | `map.zip(iterable)` | `map.zip(iterable).toMap` | `Experimental` | -| `ArrayBuilder.make` does not accept parens anymore | `ArrayBuilder.make[Int]()` | `ArrayBuilder.make[Int]` | `NewCollections`, `CrossCompat` | - -The “Automatic Migration Rule” column gives the name of the migration rule that can be used to automatically update old code to the new expected form. See [scala-collection-compat](https://github.com/scala/scala-collection-compat) for more -details on how to use it. +| `Iterable` no longer has a `sameElements` operation | `xs1.sameElements(xs2)` | `xs1.iterator.sameElements(xs2)` | `Collection213Upgrade`, `Collections213CrossCompat` | +| `collection.breakOut` no longer exists | `val xs: List[Int] = ys.map(f)(collection.breakOut)` | `val xs = ys.iterator.map(f).to(List)` | `Collection213Upgrade` | +| `zip` on `Map[K, V]` now returns an `Iterable` | `map.zip(iterable)` | `map.zip(iterable).toMap` | `Collection213Experimental` | +| `ArrayBuilder.make` does not accept parens anymore | `ArrayBuilder.make[Int]()` | `ArrayBuilder.make[Int]` | `Collection213Upgrade`, `Collections213CrossCompat` | Some classes have been removed, made private or have no equivalent in the new design: @@ -82,7 +95,7 @@ Other notable changes are: - `View`s have been completely redesigned and we expect their usage to have a more predictable evaluation model. You can read more about the new design [here](http://scala-lang.org/blog/2017/11/28/view-based-collections.html). - `mutable.ArraySeq` (which wraps an `Array[AnyRef]` in 2.12, meaning that primitives were boxed in the array) can now wrap boxed and unboxed arrays. `mutable.ArraySeq` in 2.13 is in fact equivalent to `WrappedArray` in 2.12, there are specialized subclasses for primitive arrays. Note that a `mutable.ArraySeq` can be used either way for primitive arrays (TODO: document how). `WrappedArray` is deprecated. - - There is no “default” `Factory` (previously known as `[A, C] => CanBuildFrom[Nothing, A, C]`): use `Factory[A, Vector[A]]` explicitly instead. + - There is no "default" `Factory` (previously known as `[A, C] => CanBuildFrom[Nothing, A, C]`): use `Factory[A, Vector[A]]` explicitly instead. ## Breaking changes with old syntax still supported @@ -90,20 +103,21 @@ The following table lists the changes that continue to work with a deprecation w | Description | Old Code | New Code | Automatic Migration Rule | | ----------- | -------- | -------- | ------------------------ | -| `collection.Set/Map` no longer have `+` and `-` operations | `xs + 1 - 2` | `xs ++ Set(1) -- Set(2)` | `Experimental` | +| `collection.Set/Map` no longer have `+` and `-` operations | `xs + 1 - 2` | `xs ++ Set(1) -- Set(2)` | `Collection213Experimental` | | `collection.Map` no longer have `--` operation | `map -- keys` | `map.to(immutable.Map) -- keys` | | -| `immutable.Set/Map`: the `+` operation no longer has an overload accepting multiple values | `Set(1) + (2, 3)` | `Set(1) + 2 + 3` | `NewCollections`, `CrossCompat` | -| `mutable.Set/Map` no longer have a `+` operation | `mutable.Set(1) + 2` | `mutable.Set(1).clone() += 2` | `NewCollections`, `CrossCompat` | +| `immutable.Set/Map`: the `+` operation no longer has an overload accepting multiple values | `Set(1) + (2, 3)` | `Set(1) + 2 + 3` | `Collection213Upgrade`, `Collections213CrossCompat` | +| `mutable.Map` no longer have an `updated` method | `mutable.Map(1 -> 2).updated(1, 3)` | `mutable.Map(1 -> 2).clone() += 1 -> 3` | `Collection213Upgrade`, `Collections213CrossCompat` | +| `mutable.Set/Map` no longer have a `+` operation | `mutable.Set(1) + 2` | `mutable.Set(1).clone() += 2` | `Collection213Upgrade`, `Collections213CrossCompat` | | `SortedSet`: the `to`, `until` and `from` methods are now called `rangeTo`, `rangeUntil` and `rangeFrom`, respectively | `xs.until(42)` | `xs.rangeUntil(42)` | | -| `Traversable` and `TraversableOnce` are replaced with `Iterable` and `IterableOnce`, respectively | `def f(xs: Traversable[Int]): Unit` | `def f(xs: Iterable[Int]): Unit` | `NewCollections`, `CrossCompat` | -| `Stream` is replaced with `LazyList` | `Stream.from(1)` | `LazyList.from(1)` | `RoughlyStreamToLazyList` | +| `Traversable` and `TraversableOnce` are replaced with `Iterable` and `IterableOnce`, respectively | `def f(xs: Traversable[Int]): Unit` | `def f(xs: Iterable[Int]): Unit` | `Collection213Upgrade`, `Collections213CrossCompat` | +| `Stream` is replaced with `LazyList` | `Stream.from(1)` | `LazyList.from(1)` | `Collection213Roughly` | | `Seq#union` is replaced with `concat` | `xs.union(ys)` | `xs.concat(ys)` | | -| `Stream#append` is replaced with `lazyAppendAll` | `xs.append(ys)` | `xs.lazyAppendedAll(ys)` | `NewCollections`, `CrossCompat` | -| `IterableOnce#toIterator` is replaced with `IterableOnce#iterator` | `xs.toIterator` | `xs.iterator` | `NewCollections`, `CrossCompat` | -| `copyToBuffer` has been deprecated | `xs.copyToBuffer(buffer)` | `buffer ++= xs` | `NewCollections`, `CrossCompat` | -| `TupleNZipped` has been replaced with `LazyZipN` | `(xs, ys).zipped` | `xs.lazyZip(ys)` | `NewCollections` | -| `retain` has been renamed to `filterInPlace` | `xs.retain(f)` | `xs.filterInPlace(f.tupled)` | `NewCollections` | -| `:/` and `/:` operators have been deprecated | `(xs :\ y)(f)` | `xs.foldRight(y)(f)` | `NewCollections`, `CrossCompat` | +| `Stream#append` is replaced with `lazyAppendAll` | `xs.append(ys)` | `xs.lazyAppendedAll(ys)` | `Collection213Upgrade`, `Collections213CrossCompat` | +| `IterableOnce#toIterator` is replaced with `IterableOnce#iterator` | `xs.toIterator` | `xs.iterator` | `Collection213Upgrade`, `Collections213CrossCompat` | +| `copyToBuffer` has been deprecated | `xs.copyToBuffer(buffer)` | `buffer ++= xs` | `Collection213Upgrade`, `Collections213CrossCompat` | +| `TupleNZipped` has been replaced with `LazyZipN` | `(xs, ys).zipped` | `xs.lazyZip(ys)` | `Collection213Upgrade` | +| `retain` has been renamed to `filterInPlace` | `xs.retain(f)` | `xs.filterInPlace(f.tupled)` | `Collection213Upgrade` | +| `:/` and `/:` operators have been deprecated | `(xs :\ y)(f)` | `xs.foldRight(y)(f)` | `Collection213Upgrade`, `Collections213CrossCompat` | | `companion` operation has been renamed to `iterableFactory` | `xs.companion` | `xs.iterableFactory` | | ## Deprecated things in 2.12 that have been removed in 2.13 @@ -189,6 +203,7 @@ insert and remove operations. Most usages of collections are compatible and can cross-compile 2.12 and 2.13 (at the cost of some warnings, sometimes). If you cannot get your code to cross-compile, there are various solutions: + - You can use the [`scala-collection-compat`](https://github.com/scala/scala-collection-compat) library, which makes some of 2.13's APIs available to 2.11 and 2.12. This solution does not always work, for example if your library implements custom collection types. - You can maintain a separate branch with the changes for 2.13 and publish releases for 2.13 from this branch. - You can put source files that don't cross-compile in separate directories and configure sbt to assemble the sources according to the Scala version (see also the examples below): @@ -202,10 +217,6 @@ If you cannot get your code to cross-compile, there are various solutions: } } - - You can use the [`scala-collection-compat`](https://github.com/scala/scala-collection-compat) library, which makes some of 2.13's APIs available to 2.11 and 2.12. This solution does not always work, for example if your library implements custom collection types. - -Note that the `scala-collection-compat` library has not fully stabilized yet. We expect that new, binary incompatible versions of this library will be published (for 2.11, 2.12) until Scala 2.13 is getting close to its final state. Therefore you might want to avoid adding a dependency on that library to your 2.11 / 2.12 artifacts for the time being. - Examples of libraries that cross-compile with separate source directories: - https://github.com/scala/scala-parser-combinators/pull/152 - https://github.com/scala/scala-xml/pull/222 @@ -213,118 +224,7 @@ Examples of libraries that cross-compile with separate source directories: # Collection Implementers -## `CanBuildFrom` no longer exists - what were its uses and how can they be replaced? - -`CanBuildFrom` was used to: - - generically implement transformation operations whose return type could - vary according to the type of collection elements (ie mapping a `Char` to a `Char` in a `String` - returns a `String`, but mapping a `Char` to an `Int` returns a `IndexedSeq[Int]`), - - abstract over the arity of collection type constructors (ie `List[_]` vs `Map[_, _]`), - - abstract over implicit parameters required to perform a transformation operations (ie mapping an `A` to a `B` in `SortedSet[A]` - requires an implicit `Ordering[B]` to return a `SortedSet[B]`), - - provide type-driven builders to implement generic transformation methods (eg `Future.traverse`). - -The first three points are now handled using overloading. This means that `Map[K, V]` has two overloads of `map`, -one that takes a `(K, V) => (K', V')` mapping function and returns a `Map[K', V']`, and one that takes a -`(K, V) => A` mapping function and returns an `Iterable[A]`. - -You can find more information about the design [here](http://scala-lang.org/blog/2017/05/30/tribulations-canbuildfrom.html). - -To address the last point, there is a `BuildFrom` typeclass that works exactly like the former `CanBuildFrom`. See the next section -for examples of use. - -## How can I write generic extension methods? - -Depending on the level of desired genericity, several solutions can apply, with different complexity. - -### Write an operation that can consume any collection - -Take an `IterableOnce[A]` as parameter, or an `Iterable[A]` if you need more than one -traversals: - -~~~ scala -implicit class SumByOperation[A](coll: IterableOnce[A]) { - def sumBy[B](f: A => B)(implicit num: Numeric[B]): B = { - val it = coll.iterator - var result = f(it.next()) - while (it.hasNext()) { - result = num.plus(result, it.next()) - } - result - } -} -~~~ - -### Write an operation that returns another collection - -Use `BuildFrom`: - -~~~ scala -def optionSequence[CC[X] <: Iterable[X], A, To](xs: CC[Option[A]])(implicit bf: BuildFrom[CC[Option[A]], A, To]): Option[To] = - xs.foldLeft[Option[Builder[A, To]]](Some(bf.newBuilder(xs))) { - case (Some(builder), Some(a)) => Some(builder += a) - case _ => None - }.map(_.result()) -~~~ - -The `optionSequence` operation can be used on any collection (but not on an `Array` or a `String`): - -~~~ -scala> optionSequence(List[Option[Int]](Some(1), Some(2), Some(3))) -res1: Option[List[Int]] = Some(List(1, 2, 3)) - -scala> optionSequence(Set[Option[(Int, String)]](Some(1 -> "foo"), Some(2 -> "bar")))(TreeMap) // Force the result type -res4: Option[scala.collection.immutable.TreeMap[Int,String]] = Some(TreeMap(1 -> foo, 2 -> bar)) -~~~ - -### Write an operation that can also be applied to a `View`, an `Array` or `String` - -For more advanced cases, or if your operation should also work with `Array`s, `String`s and `View`s, -the pattern given in the previous section is not enough. - -The [`scala-collection-contrib`](https://github.com/scala/scala-collection-contrib) module -provides a more advanced machinery that handles that: - -~~~ scala -class IntersperseOperation[C, S <: HasSeqOps[C]](coll: C)(implicit val seq: S) { - def intersperse[B >: seq.A, That](sep: B)(implicit bf: BuildFrom[C, B, That]): That = - bf.fromSpecificIterable(coll)(new View.Intersperse(seq(coll), sep)) // (Assume that there is a `View.Intersperse` implemented somewhere) -} - -implicit def IntersperseOperation[C](coll: C)(implicit seq: HasSeqOps[C]): SeqDecorator[C, seq.type] = - new IntersperseOperation(coll)(seq) -~~~ - -This pattern makes the `intersperse` operation available to any `Seq` _like_ type (eg. a `SeqView`, an `Array` or a `String`). - -## How do I integrate my collection in the new design? - -See the [online documentation]({{ site.baseurl }}/overviews/core/custom-collections.html) - -The API of the template traits has changed: -- they used to be suffixed by “Like” (e.g. `SeqLike`), whereas they are now suffixed by “Ops” (e.g. `SeqOps`), -- they used to abstract over the collection type of transformation operations, they now abstract over both - the collection type and the collection type constructor: `SeqLike[+A, +Repr]` has been replaced with - `SeqOps[+A, +CC[_], +C]`. - -## Which methods should I overload to support the “same result type” principle? - -You want to add overloads to specialize a transformation operations such that they return a more specific result. Examples are: -- `map`, on `StringOps`, when the mapping function returns a `Char`, should return a `String` (instead of an `IndexedSeq`), -- `map`, on `Map`, when the mapping function returns a pair, should return a `Map` (instead of an `Iterable`), -- `map`, on `SortedSet`, when an implicit `Ordering` is available for the resulting element type, should return a -`SortedSet` (instead of a `Set`). - -The following table lists transformation operations that might return a too wide type. You might want to overload -these operations to return a more specific type. - - Collection | Operations ----------------|-------------- -`Iterable` | `map`, `flatMap`, `collect`, `scanLeft`, `scanRight`, `groupMap`, `concat`, `zip`, `zipWithIndex`, `zipAll`, `unzip` -`Seq` | `prepended`, `appended`, `prependedAll`, `appendedAll`, `padTo`, `patch` -`immutable.Seq`| `updated` -`SortedSet` | `map`, `flatMap`, `collect`, `zip` -`Map` | `map`, `flatMap`, `collect`, `concat` -`immutable.Map`| `updated`, `transform` -`SortedMap` | `map`, `flatMap`, `collect`, `concat` -`immutable.SortedMap` | `updated` +To learn about differences when implementing custom collection types or operations, see the following documents: + - [The architecture of Scala collections]({{ site.baseurl }}/overviews/core/architecture-of-scala-213-collections.html) + - [Implementing custom collections]({{ site.baseurl }}/overviews/core/custom-collections.html) + - [Adding custom collection operations]({{ site.baseurl }}/overviews/core/custom-collection-operations.html) \ No newline at end of file From a0fd98a7a236e213261d411daf010ed0cbdb43a3 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Mon, 29 Apr 2019 12:02:37 +0200 Subject: [PATCH 0459/3075] review feedback --- _overviews/core/collections-migration-213.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_overviews/core/collections-migration-213.md b/_overviews/core/collections-migration-213.md index 10bcb21dbf..10f9d75e52 100644 --- a/_overviews/core/collections-migration-213.md +++ b/_overviews/core/collections-migration-213.md @@ -165,10 +165,11 @@ def filterInPlace(p: A => Boolean): this.type def patchInPlace(from: Int, patch: scala.collection.Seq[A], replaced: Int): this.type ~~~ -Another new operation is `distinctBy`: +Other new operations are `distinctBy` and `partitionMap` ~~~ scala -def distinctBy[B](f: A => B): C // (Where `C` can be `List[Int]`, for instance) +def distinctBy[B](f: A => B): C // `C` can be `List[Int]`, for instance +def partitionMap[A1, A2](f: A => Either[A1, A2]): (CC[A1], CC[A2]) // `CC` can be `List`, for instance ~~~ Last, additional operations are provided by the `scala-collection-contrib` module. You can From ba9ba4ad39cf0ebe08a8ab3e6e472ce93a6b488b Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Mon, 29 Apr 2019 14:11:19 +0200 Subject: [PATCH 0460/3075] allow scrolling tables --- _overviews/core/collections-migration-213.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/_overviews/core/collections-migration-213.md b/_overviews/core/collections-migration-213.md index 10f9d75e52..f58bad8e9f 100644 --- a/_overviews/core/collections-migration-213.md +++ b/_overviews/core/collections-migration-213.md @@ -34,6 +34,8 @@ The module also provides [migratrion rules](https://github.com/scala/scala-colle The following table summarizes the breaking changes. The "Automatic Migration Rule" column gives the name of the migration rule that can be used to automatically update old code to the new expected form. +
+ | Description | Old Code | New Code | Automatic Migration Rule | | ----------- | -------- | -------- | ------------------------ | | Method `to[C[_]]` has been removed (it might be reintroduced but deprecated, though) | `xs.to[List]` | `xs.to(List)` | `Collection213Upgrade`, `Collections213CrossCompat` | @@ -43,6 +45,8 @@ The following table summarizes the breaking changes. The "Automatic Migration Ru | `zip` on `Map[K, V]` now returns an `Iterable` | `map.zip(iterable)` | `map.zip(iterable).toMap` | `Collection213Experimental` | | `ArrayBuilder.make` does not accept parens anymore | `ArrayBuilder.make[Int]()` | `ArrayBuilder.make[Int]` | `Collection213Upgrade`, `Collections213CrossCompat` | +
+ Some classes have been removed, made private or have no equivalent in the new design: - `ArrayStack` @@ -101,6 +105,8 @@ Other notable changes are: The following table lists the changes that continue to work with a deprecation warning. +
+ | Description | Old Code | New Code | Automatic Migration Rule | | ----------- | -------- | -------- | ------------------------ | | `collection.Set/Map` no longer have `+` and `-` operations | `xs + 1 - 2` | `xs ++ Set(1) -- Set(2)` | `Collection213Experimental` | @@ -119,7 +125,9 @@ The following table lists the changes that continue to work with a deprecation w | `retain` has been renamed to `filterInPlace` | `xs.retain(f)` | `xs.filterInPlace(f.tupled)` | `Collection213Upgrade` | | `:/` and `/:` operators have been deprecated | `(xs :\ y)(f)` | `xs.foldRight(y)(f)` | `Collection213Upgrade`, `Collections213CrossCompat` | | `companion` operation has been renamed to `iterableFactory` | `xs.companion` | `xs.iterableFactory` | | - + +
+ ## Deprecated things in 2.12 that have been removed in 2.13 - `collection.convert.JavaConversions`. Use `collection.convert.JavaConverters` instead ; From db7c58b57daf28e874b4fe01c0b2df3168aa875c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Tue, 30 Apr 2019 18:09:44 +0200 Subject: [PATCH 0461/3075] Fix the sentence that says how SIP committee members are elected. This is not a change of the actual process. We've always done it that way (or least as far as I've been in the committee). --- _sips/sip-submission.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_sips/sip-submission.md b/_sips/sip-submission.md index b40800b5d0..c30a4ae96c 100644 --- a/_sips/sip-submission.md +++ b/_sips/sip-submission.md @@ -190,8 +190,9 @@ Committee members should be either individuals responsible for a specific part of the Scala codebase, committers or contributors of the Scala compiler. Exceptionally, members may also be important representatives of the community with a high technical knowledge to understand the implications of every proposal -and participate into the discussions. The members are elected by the Process -Lead based on their expertise and implication in the community. +and participate into the discussions. New members are elected by existing +members of the SIP Committee, based on their expertise and involvement in the +community. The current committee members are: From ff6a56bab84958abc40fc5fb6cd86efb57e2f147 Mon Sep 17 00:00:00 2001 From: Gabriel Claramunt Date: Wed, 1 May 2019 12:57:26 -0300 Subject: [PATCH 0462/3075] Update basics.md --- _es/tour/basics.md | 288 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 288 insertions(+) diff --git a/_es/tour/basics.md b/_es/tour/basics.md index bd86428a9b..78464b51d1 100644 --- a/_es/tour/basics.md +++ b/_es/tour/basics.md @@ -7,3 +7,291 @@ discourse: false partof: scala-tour language: es --- + +# Scala básico + + +## Expresiones + +En Scala todo es una expresión (cada sentencia "devuelve" un valor). + +```scala +1 + 1 +``` + +Se puede ver el resultado de evaluar expresiones usando println. + +```scala +println(1) // 1 +println(1 + 1) // 2 +println("Hello!") // Hello! +println("Hello," + " world!") // Hello, world! +``` + +## Valores + +Se puede nombrar el resultado de expresiones con la palabra clave *val*. + +```scala +val x = 1 + 1 +println(x) // 2 +``` + +Los resultados con nombre, como x en el ejemplo, son llamados *valores*. Referenciar un valor no lo vuelve a computar. + +Los valores no pueden ser reasignados. + +```scala +x = 3 // This does not compile. +``` + +Los tipos de los valores pueden ser inferidos, pero tambien se pueden anotar explicitamente de la siguiente forma: + +```scala +val x: Int = 1 + 1 +``` + +Noten como la declaración de tipo Int va después del identificador. + +## Variables + +Las variables son como los valores, excepto que no es posible re-asignarlos. Las variables se definen con la palabra clave *var*. + +```scala +var x = 1 + 1 +x = 3 // This compiles because "x" is declared with the "var" keyword. +println(x * x) // 9 +``` + +Igual que con los valores, si queremos se puede especificar el tipo: + +```scala +var x: Int = 1 + 1 +``` + +## Bloques + +Se pueden combinar expresiones rodeándolas con { y } . A esto le llamamos un *bloque*. + +El resultado de la ultima expresión del bloque es también el resultado total del bloque. + +```scala +println({ + val x = 1 + 1 + x + 1 +}) // 3 +``` + +## Funciones + +Las funciones son expresiones que reciben parámetros. + +Se pueden definir funciones anónimas, por ejemplo, una que retorne x + 1 para x entero: + +```scala +(x: Int) => x + 1 +``` + +A la izquierda de => esta la lista de parámetros. A la derecha esta el cuerpo de la función + +También podemos asignarle un nombre a la función. + +```scala +val addOne = (x: Int) => x + 1 +println(addOne(1)) // 2 +``` + +Las funciones pueden tomar muchos parámetros. + +```scala +val add = (x: Int, y: Int) => x + y +println(add(1, 2)) // 3 +``` + +O ninguno. + +```scala +val getTheAnswer = () => 42 +println(getTheAnswer()) // 42 +``` + + +## Métodos + +Los métodos se parecen y se comportan de forma muy similar a las funciones, pero hay un par de diferencias clave entre ellos. +Los métodos se definen con la palabra clave *def*, seguida por un nombre, una lista de parámetros, un tipo de retorno (opcional pero recomendado), y el cuerpo del método. + +```scala +def add(x: Int, y: Int): Int = x + y +println(add(1, 2)) // 3 +``` + +Notar como el tipo de retorno es declarado después de la lista de parámetros y con dos puntos. + +Los métodos pueden tener mutiles listas de parámetros. + +```scala +def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier +println(addThenMultiply(1, 2)(3)) // 9 +``` + +O ninguna. + +```scala +def name: String = System.getProperty("user.name") +println("Hello, " + name + "!") +``` + +Hay otras diferencias, pero para simplificar, podemos pensar que son similares a las funciones. + +Los métodos también pueden tener expresiones de varias lineas. + +```scala +def getSquareString(input: Double): String = { + val square = input * input + square.toString +} +``` + +La ultima expresión en el cuerpo del método es el valor de retorno del mismo. +(Scala tiene la palabra clave *return* pero no se usa y no hace lo que uds. piensan que hace) + +## Clases + +Se puede definir clases con la palabra clave *class* seguida del nombre y los parámetros del constructor. + +```scala +class Greeter(prefix: String, suffix: String) { + def greet(name: String): Unit = + println(prefix + name + suffix) +} +``` + +El tipo de retorno del método greet es Unit, que dice que no hay nada significativo que retornar. Se usa de forma similar al void de Java y C (con la diferencia de que como toda expresión en Scala debe retornar un valor, existe un valor singleton para el tipo Unit que se escribe `()` y no lleva información ) + +Puedes crear una instancia de una clase con la palabra clave *new*. + +```scala +val greeter = new Greeter("Hello, ", "!") +greeter.greet("Scala developer") // Hello, Scala developer! +``` + +Mas adelante, cubriremos las clases en profundidad. + +## Case Classes + +Scala tiene un tipo especial de clases llamadas "case" classes. Por defecto, las case classes son inmutables y son comparadas por valor. +Las case classes se definen usando las palabras clave *case class*. + +```scala +case class Point(x: Int, y: Int) +``` + +Se pueden instanciar sin necesidad de usar la palabra clave new. + +```scala +val point = Point(1, 2) +val anotherPoint = Point(1, 2) +val yetAnotherPoint = Point(2, 2) +``` + +Y son comparadas por valor. + +```scala +if (point == anotherPoint) { + println(point + " and " + anotherPoint + " are the same.") +} else { + println(point + " and " + anotherPoint + " are different.") +} // Point(1,2) and Point(1,2) are the same. + +if (point == yetAnotherPoint) { + println(point + " and " + yetAnotherPoint + " are the same.") +} else { + println(point + " and " + yetAnotherPoint + " are different.") +} // Point(1,2) and Point(2,2) are different. +``` + +Hay mucho mas sobre las case classes que queremos presentar, y estamos convencidos de que te vas a enamorar de ellas. Las cubriremos en profundidad mas adelante. + +## Objetos + +Los objetos son instancias de una sola clase de su propia definición. Puedes pensar en ellos como singleton de sus propias clases + +Puedes definir objectos con la palabra clave *object*. + +```scala +object IdFactory { + private var counter = 0 + def create(): Int = { + counter += 1 + counter + } +} +``` + +Para acceder al objeto, lo referencias por su nombre. + +```scala +val newId: Int = IdFactory.create() +println(newId) // 1 +val newerId: Int = IdFactory.create() +println(newerId) // 2 +``` + +Mas adelante, cubriremos los objetos en profundidad. + +## Traits + +Los traits son tipos que contienen campos y métodos. Se pueden combinar múltiples traits. + +Los traits se definen con la palabra clave *trait*. + +```scala +trait Greeter { + def greet(name: String): Unit +} +``` + +Los traits pueden también tener implementación por defecto. + +```scala +trait Greeter { + def greet(name: String): Unit = + println("Hello, " + name + "!") +} +``` + +También puedes extender traits con la palabra clave *extends* y sobrescribir una implementación con la palabra clave *override* . + +```scala +class DefaultGreeter extends Greeter + +class CustomizableGreeter(prefix: String, postfix: String) extends Greeter { + override def greet(name: String): Unit = { + println(prefix + name + postfix) + } +} + +val greeter = new DefaultGreeter() +greeter.greet("Scala developer") // Hello, Scala developer! + +val customGreeter = new CustomizableGreeter("How are you, ", "?") +customGreeter.greet("Scala developer") // How are you, Scala developer? +``` + +Aquí, DefaultGreeter extiende un solo trait, pero puede extender múltiples traits. + +Mas adelante, cubriremos los traits en profundidad. + +## Metodo principal (Main Method) + +El metodo principal (main) es el punto de entrada de un programa. La maquina virtual de java (JVM) requiere que el método principal sea llamado `main` y que tome un solo argumento: un arrray de Strings. + +Usando un objeto, puedes definir el método principal de la siguiente forma: + +```scala +object Main { + def main(args: Array[String]): Unit = + println("Hello, Scala developer!") +} +``` From bf99da257277f91cd6ba36954558c359d16594a4 Mon Sep 17 00:00:00 2001 From: Dale Wijnand <344610+dwijnand@users.noreply.github.com> Date: Thu, 2 May 2019 07:53:05 +0100 Subject: [PATCH 0463/3075] Linkify the Oracle LTS support URL --- _overviews/jdk-compatibility/overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/jdk-compatibility/overview.md b/_overviews/jdk-compatibility/overview.md index b776a87a6b..117e52b90b 100644 --- a/_overviews/jdk-compatibility/overview.md +++ b/_overviews/jdk-compatibility/overview.md @@ -27,7 +27,7 @@ This table shows the first Scala release in each series that works with each JVM We recommend using Java 8 for *compiling* Scala code. Since the JVM is backward compatible, it is usually safe to use a newer JVM to *run* your code compiled by the Scala compiler for older JVM versions. There are notable exceptions with experimental/unsafe features, and the introduction of the module system in Java 9. The Scala compiler does usually need updates to run properly on newer versions of the JVM, so make sure to use the appropriate JVM when compiling your code. -We try to provide experimental support for running the Scala compiler on LTS versions of Java ("Long Term Support"; see http://www.oracle.com/technetwork/java/eol-135779.html), and to the extent possible will include the current LTS Java version in our CI matrix and the community build. We will not, a priori, consider non-LTS Java versions. Compiler bugs related to Java versions other than the supported one (Java 8), will be scheduled with lower priority, and will not be considered release blockers. Lightbend does offer commercial support for faster resolution of issues like this. +We try to provide experimental support for running the Scala compiler on LTS versions of Java ("Long Term Support"; see ), and to the extent possible will include the current LTS Java version in our CI matrix and the community build. We will not, a priori, consider non-LTS Java versions. Compiler bugs related to Java versions other than the supported one (Java 8), will be scheduled with lower priority, and will not be considered release blockers. Lightbend does offer commercial support for faster resolution of issues like this. Scala code compiled on Java 8 should run without problems in later JVMs, and we will give higher priority to bugs that break this property. For example, in the 2.13.x series we intend to provide support for JPMS module access checks, to allow ensuring your code won't incur `LinkageErrors` due to module access violations. From 9263c69c11ed51379e47b277db50901a8bdca563 Mon Sep 17 00:00:00 2001 From: Gabriel Claramunt Date: Sat, 4 May 2019 14:36:31 -0300 Subject: [PATCH 0464/3075] fix formatting and scalafiddle --- _es/tour/basics.md | 138 +++++++++++++++++++++++++++------------------ 1 file changed, 83 insertions(+), 55 deletions(-) diff --git a/_es/tour/basics.md b/_es/tour/basics.md index 78464b51d1..24819b1d86 100644 --- a/_es/tour/basics.md +++ b/_es/tour/basics.md @@ -6,58 +6,77 @@ discourse: false partof: scala-tour language: es + +num: 2 +next-page: unified-types +previous-page: tour-of-scala --- -# Scala básico +En esta página, cubriremos lo básico de Scala. + +## Probando Scala en el navegador + +Puedes ejecutar Scala en tu navegador con ScalaFiddle. + +1. Ve a [https://scalafiddle.io](https://scalafiddle.io). +2. Pega `println("Hello, world!")` en el panel izquierdo. +3. Presiona el botón de "Run". El resultado aparece en el panel de la derecha. +Esta es una forma simple y con cero configuración de experimentar con piezas de código en Scala. + +Many of the code examples in this documentation are also integrated with ScalaFiddle, so you +can directly experiment with them simply by clicking the Run-button. +Muchos de los ejemplos de código en esta documentación están integrados también con ScalaFiddle, para que puedas experimentar directamente con ellos simplemente presionando el botón de "Run". ## Expresiones En Scala todo es una expresión (cada sentencia "devuelve" un valor). -```scala +```tut 1 + 1 ``` -Se puede ver el resultado de evaluar expresiones usando println. +Se puede ver el resultado de evaluar expresiones usando `println`. -```scala +{% scalafiddle %} +```tut println(1) // 1 println(1 + 1) // 2 println("Hello!") // Hello! println("Hello," + " world!") // Hello, world! ``` +{% endscalafiddle %} ## Valores -Se puede nombrar el resultado de expresiones con la palabra clave *val*. +Se puede nombrar el resultado de expresiones con la palabra clave `val`. -```scala +```tut val x = 1 + 1 println(x) // 2 ``` -Los resultados con nombre, como x en el ejemplo, son llamados *valores*. Referenciar un valor no lo vuelve a computar. +Los resultados con nombre, como `x` en el ejemplo, son llamados valores. Referenciar un valor no lo vuelve a computar. Los valores no pueden ser reasignados. -```scala +```tut:fail x = 3 // This does not compile. ``` -Los tipos de los valores pueden ser inferidos, pero tambien se pueden anotar explicitamente de la siguiente forma: +Los tipos de los valores pueden ser inferidos, pero también se pueden anotar explicitamente de la siguiente forma: -```scala +```tut val x: Int = 1 + 1 ``` -Noten como la declaración de tipo Int va después del identificador. +Noten como la declaración de tipo `Int` va después del identificador `x`. También necesitas un `:`. ## Variables -Las variables son como los valores, excepto que no es posible re-asignarlos. Las variables se definen con la palabra clave *var*. +Las variables son como los valores, excepto que no es posible re-asignarlos. Las variables se definen con la palabra clave `var`. -```scala +```tut var x = 1 + 1 x = 3 // This compiles because "x" is declared with the "var" keyword. println(x * x) // 9 @@ -65,17 +84,17 @@ println(x * x) // 9 Igual que con los valores, si queremos se puede especificar el tipo: -```scala +```tut var x: Int = 1 + 1 ``` ## Bloques -Se pueden combinar expresiones rodeándolas con { y } . A esto le llamamos un *bloque*. +Se pueden combinar expresiones rodeándolas con `{}` . A esto le llamamos un bloque. El resultado de la ultima expresión del bloque es también el resultado total del bloque. -```scala +```tut println({ val x = 1 + 1 x + 1 @@ -88,7 +107,7 @@ Las funciones son expresiones que reciben parámetros. Se pueden definir funciones anónimas, por ejemplo, una que retorne x + 1 para x entero: -```scala +```tut (x: Int) => x + 1 ``` @@ -96,48 +115,56 @@ A la izquierda de => esta la lista de parámetros. A la derecha esta el cuerpo d También podemos asignarle un nombre a la función. -```scala +{% scalafiddle %} +```tut val addOne = (x: Int) => x + 1 println(addOne(1)) // 2 ``` +{% endscalafiddle %} Las funciones pueden tomar muchos parámetros. -```scala +{% scalafiddle %} +```tut val add = (x: Int, y: Int) => x + y println(add(1, 2)) // 3 ``` +{% endscalafiddle %} O ninguno. -```scala +```tut val getTheAnswer = () => 42 println(getTheAnswer()) // 42 ``` - ## Métodos Los métodos se parecen y se comportan de forma muy similar a las funciones, pero hay un par de diferencias clave entre ellos. -Los métodos se definen con la palabra clave *def*, seguida por un nombre, una lista de parámetros, un tipo de retorno (opcional pero recomendado), y el cuerpo del método. -```scala +Los métodos se definen con la palabra clave `def`, seguida por un nombre, una lista de parámetros, un tipo de retorno, y el cuerpo del método. + +{% scalafiddle %} +```tut def add(x: Int, y: Int): Int = x + y println(add(1, 2)) // 3 ``` +{% endscalafiddle %} -Notar como el tipo de retorno es declarado después de la lista de parámetros y con dos puntos. +Notar como el tipo de retorno es declarado _después_ de la lista de parámetros y con dos puntos `: Int`. Los métodos pueden tener mutiles listas de parámetros. -```scala +{% scalafiddle %} +```tut def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier println(addThenMultiply(1, 2)(3)) // 9 ``` +{% endscalafiddle %} -O ninguna. +O ninguna lista de parametros. -```scala +```tut def name: String = System.getProperty("user.name") println("Hello, " + name + "!") ``` @@ -146,7 +173,7 @@ Hay otras diferencias, pero para simplificar, podemos pensar que son similares a Los métodos también pueden tener expresiones de varias lineas. -```scala +```tut def getSquareString(input: Double): String = { val square = input * input square.toString @@ -154,42 +181,42 @@ def getSquareString(input: Double): String = { ``` La ultima expresión en el cuerpo del método es el valor de retorno del mismo. -(Scala tiene la palabra clave *return* pero no se usa y no hace lo que uds. piensan que hace) +(Scala tiene la palabra clave `return` pero raramente se usa) ## Clases -Se puede definir clases con la palabra clave *class* seguida del nombre y los parámetros del constructor. +Se puede definir clases con la palabra clave `class` seguida del nombre y los parámetros del constructor. -```scala +```tut class Greeter(prefix: String, suffix: String) { def greet(name: String): Unit = println(prefix + name + suffix) } ``` -El tipo de retorno del método greet es Unit, que dice que no hay nada significativo que retornar. Se usa de forma similar al void de Java y C (con la diferencia de que como toda expresión en Scala debe retornar un valor, existe un valor singleton para el tipo Unit que se escribe `()` y no lleva información ) +El tipo de retorno del método `greet` es `Unit`, que dice que no hay nada significativo que retornar. Se usa de forma similar al `void` de Java y C (Con la diferencia de que como toda expresión en Scala debe retornar un valor, existe un valor singleton para el tipo Unit que se escribe () y no lleva información ) Puedes crear una instancia de una clase con la palabra clave *new*. -```scala +```tut val greeter = new Greeter("Hello, ", "!") greeter.greet("Scala developer") // Hello, Scala developer! ``` -Mas adelante, cubriremos las clases en profundidad. +Cubriremos las clases en profundidad [mas adelante](classes.html). ## Case Classes Scala tiene un tipo especial de clases llamadas "case" classes. Por defecto, las case classes son inmutables y son comparadas por valor. -Las case classes se definen usando las palabras clave *case class*. +Las case classes se definen usando las palabras clave `case class`. -```scala +```tut case class Point(x: Int, y: Int) ``` -Se pueden instanciar sin necesidad de usar la palabra clave new. +Se pueden instanciar sin necesidad de usar la palabra clave `new`. -```scala +```tut val point = Point(1, 2) val anotherPoint = Point(1, 2) val yetAnotherPoint = Point(2, 2) @@ -197,7 +224,7 @@ val yetAnotherPoint = Point(2, 2) Y son comparadas por valor. -```scala +```tut if (point == anotherPoint) { println(point + " and " + anotherPoint + " are the same.") } else { @@ -211,15 +238,15 @@ if (point == yetAnotherPoint) { } // Point(1,2) and Point(2,2) are different. ``` -Hay mucho mas sobre las case classes que queremos presentar, y estamos convencidos de que te vas a enamorar de ellas. Las cubriremos en profundidad mas adelante. +Hay mucho mas sobre las case classes que queremos presentar, y estamos convencidos de que te vas a enamorar de ellas. Las cubriremos en profundidad [mas adelante](case-classes.html). ## Objetos Los objetos son instancias de una sola clase de su propia definición. Puedes pensar en ellos como singleton de sus propias clases -Puedes definir objectos con la palabra clave *object*. +Puedes definir objectos con la palabra clave `object`. -```scala +```tut object IdFactory { private var counter = 0 def create(): Int = { @@ -231,22 +258,22 @@ object IdFactory { Para acceder al objeto, lo referencias por su nombre. -```scala +```tut val newId: Int = IdFactory.create() println(newId) // 1 val newerId: Int = IdFactory.create() println(newerId) // 2 ``` -Mas adelante, cubriremos los objetos en profundidad. +Cubriremos los objetos en profundidad [mas adelante](singleton-objects.html). ## Traits Los traits son tipos que contienen campos y métodos. Se pueden combinar múltiples traits. -Los traits se definen con la palabra clave *trait*. +Los traits se definen con la palabra clave `trait`. -```scala +```tut trait Greeter { def greet(name: String): Unit } @@ -254,16 +281,16 @@ trait Greeter { Los traits pueden también tener implementación por defecto. -```scala +{% scalafiddle %} +```tut trait Greeter { def greet(name: String): Unit = println("Hello, " + name + "!") } -``` -También puedes extender traits con la palabra clave *extends* y sobrescribir una implementación con la palabra clave *override* . +También puedes extender traits con la palabra clave `extends` y sobrescribir una implementación con la palabra clave `override` . -```scala +```tut class DefaultGreeter extends Greeter class CustomizableGreeter(prefix: String, postfix: String) extends Greeter { @@ -278,18 +305,19 @@ greeter.greet("Scala developer") // Hello, Scala developer! val customGreeter = new CustomizableGreeter("How are you, ", "?") customGreeter.greet("Scala developer") // How are you, Scala developer? ``` +{% endscalafiddle %} -Aquí, DefaultGreeter extiende un solo trait, pero puede extender múltiples traits. +Aquí, `DefaultGreeter` extiende un solo trait, pero puede extender múltiples traits. -Mas adelante, cubriremos los traits en profundidad. +Cubriremos los traits en profundidad [mas adelante](traits.html). -## Metodo principal (Main Method) +## Método principal (Main Method) -El metodo principal (main) es el punto de entrada de un programa. La maquina virtual de java (JVM) requiere que el método principal sea llamado `main` y que tome un solo argumento: un arrray de Strings. +El método principal (main) es el punto de entrada de un programa. La maquina virtual de java (JVM) requiere que el método principal sea llamado `main` y que tome un solo argumento: un arrray de Strings. Usando un objeto, puedes definir el método principal de la siguiente forma: -```scala +```tut object Main { def main(args: Array[String]): Unit = println("Hello, Scala developer!") From 0ff8f50cacaf22ceaca3102251d035689f5e54ac Mon Sep 17 00:00:00 2001 From: Gabriel Claramunt Date: Sat, 4 May 2019 23:14:13 -0300 Subject: [PATCH 0465/3075] add missing closing quotes --- _es/tour/basics.md | 1 + 1 file changed, 1 insertion(+) diff --git a/_es/tour/basics.md b/_es/tour/basics.md index 24819b1d86..2b613c7bec 100644 --- a/_es/tour/basics.md +++ b/_es/tour/basics.md @@ -287,6 +287,7 @@ trait Greeter { def greet(name: String): Unit = println("Hello, " + name + "!") } +``` También puedes extender traits con la palabra clave `extends` y sobrescribir una implementación con la palabra clave `override` . From 16c153cc515aa141f37e39305c01aefd961e6089 Mon Sep 17 00:00:00 2001 From: "Diego E. Alonso Blas" Date: Sun, 5 May 2019 23:59:11 -0300 Subject: [PATCH 0466/3075] Apply suggestions from code review Co-Authored-By: gclaramunt --- _es/tour/basics.md | 50 +++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/_es/tour/basics.md b/_es/tour/basics.md index 2b613c7bec..c8f45e7c5a 100644 --- a/_es/tour/basics.md +++ b/_es/tour/basics.md @@ -19,14 +19,14 @@ En esta página, cubriremos lo básico de Scala. Puedes ejecutar Scala en tu navegador con ScalaFiddle. 1. Ve a [https://scalafiddle.io](https://scalafiddle.io). -2. Pega `println("Hello, world!")` en el panel izquierdo. -3. Presiona el botón de "Run". El resultado aparece en el panel de la derecha. +2. Escribe `println("Hello, world!")` en el panel a la izquierda. +3. Presiona el botón "Run". En el panel de la derecha aparecerá el resultado. -Esta es una forma simple y con cero configuración de experimentar con piezas de código en Scala. +Así, de manera fácil y sin preparación, puedes probar fragmentos de código Scala. Many of the code examples in this documentation are also integrated with ScalaFiddle, so you can directly experiment with them simply by clicking the Run-button. -Muchos de los ejemplos de código en esta documentación están integrados también con ScalaFiddle, para que puedas experimentar directamente con ellos simplemente presionando el botón de "Run". +Muchos ejemplos de código en esta documentación están integrados con ScalaFiddle, y así puedes probarlos directamente solo con pulsar el botón "Run". ## Expresiones @@ -49,7 +49,7 @@ println("Hello," + " world!") // Hello, world! ## Valores -Se puede nombrar el resultado de expresiones con la palabra clave `val`. +Se puede dar un nombre al resultado de una expresión usando la palabra reservada `val`. ```tut val x = 1 + 1 @@ -74,7 +74,7 @@ Noten como la declaración de tipo `Int` va después del identificador `x`. Tamb ## Variables -Las variables son como los valores, excepto que no es posible re-asignarlos. Las variables se definen con la palabra clave `var`. +Una variable es como un valor, excepto que a una variable se le puede re-asignar un valor después de declararla. Una variable se declara con la palabra reservada `var`. ```tut var x = 1 + 1 @@ -82,7 +82,7 @@ x = 3 // This compiles because "x" is declared with the "var" keyword. println(x * x) // 9 ``` -Igual que con los valores, si queremos se puede especificar el tipo: +Como con los valores, si se quiere se puede especificar el tipo de una variable mutable: ```tut var x: Int = 1 + 1 @@ -103,7 +103,7 @@ println({ ## Funciones -Las funciones son expresiones que reciben parámetros. +Una función es una expresión que acepta parámetros. Se pueden definir funciones anónimas, por ejemplo, una que retorne x + 1 para x entero: @@ -111,7 +111,7 @@ Se pueden definir funciones anónimas, por ejemplo, una que retorne x + 1 para x (x: Int) => x + 1 ``` -A la izquierda de => esta la lista de parámetros. A la derecha esta el cuerpo de la función +La lista de parámetros de la función está a la izquierda de la flecha `=>`, y a su derecha está el cuerpo de la función. También podemos asignarle un nombre a la función. @@ -140,9 +140,9 @@ println(getTheAnswer()) // 42 ## Métodos -Los métodos se parecen y se comportan de forma muy similar a las funciones, pero hay un par de diferencias clave entre ellos. +Los métodos se parecen y comportan casi como a las funciones, pero se diferencian en dos aspectos clave: -Los métodos se definen con la palabra clave `def`, seguida por un nombre, una lista de parámetros, un tipo de retorno, y el cuerpo del método. +Un método se define con la palabra reservada `def`, seguida por el nombre del método, la lista de parámetros, el tipo de valores que el método devuelve, y el cuerpo del método. {% scalafiddle %} ```tut @@ -151,9 +151,9 @@ println(add(1, 2)) // 3 ``` {% endscalafiddle %} -Notar como el tipo de retorno es declarado _después_ de la lista de parámetros y con dos puntos `: Int`. +Observe que el tipo de retorno se declara _después_ de la lista de parámetros, y separado con dos puntos, e.g. `: Int`. -Los métodos pueden tener mutiles listas de parámetros. +Un método puede tener varias listas de parámetros {% scalafiddle %} ```tut @@ -181,11 +181,11 @@ def getSquareString(input: Double): String = { ``` La ultima expresión en el cuerpo del método es el valor de retorno del mismo. -(Scala tiene la palabra clave `return` pero raramente se usa) +(Scala tiene una palabra reservada `return`, pero se usa raramente, y no se aconseja usarla) ## Clases -Se puede definir clases con la palabra clave `class` seguida del nombre y los parámetros del constructor. +Una clase se define con la palabra reservada `class`, seguida del nombre, y la lista de parámetros del constructor. ```tut class Greeter(prefix: String, suffix: String) { @@ -194,27 +194,27 @@ class Greeter(prefix: String, suffix: String) { } ``` -El tipo de retorno del método `greet` es `Unit`, que dice que no hay nada significativo que retornar. Se usa de forma similar al `void` de Java y C (Con la diferencia de que como toda expresión en Scala debe retornar un valor, existe un valor singleton para el tipo Unit que se escribe () y no lleva información ) +El método `greet` tiene un tipo de retorno `Unit`, que indica que el método no tiene nada significativo que devolver. Esto es similar al tipo `void` en C, C++, o Java. La diferencia con estos lenguajes es que, dado que en Scala toda expresión debe devuelvor un valor, se usa un tipo `Unit`, con un solo valor, que se escribe `()` y no lleva información. -Puedes crear una instancia de una clase con la palabra clave *new*. +Se puede crear una instancia de una clase con la palabra reservada *new*. ```tut val greeter = new Greeter("Hello, ", "!") greeter.greet("Scala developer") // Hello, Scala developer! ``` -Cubriremos las clases en profundidad [mas adelante](classes.html). +Las clases se tratan en profundidad [mas adelante](classes.html). ## Case Classes -Scala tiene un tipo especial de clases llamadas "case" classes. Por defecto, las case classes son inmutables y son comparadas por valor. -Las case classes se definen usando las palabras clave `case class`. +Hay un tipo especial de clases en Scala, las llamadas "case" classes. Por defecto, las instancias de una case class son inmutables, y se comparan con otras solo por los valores que contienen en cada campo. +Una case class se define con las palabras reservadas `case class`: ```tut case class Point(x: Int, y: Int) ``` -Se pueden instanciar sin necesidad de usar la palabra clave `new`. +Se puede crear una instancia de una `case class`, sin usar la palabra reservada `new`. ```tut val point = Point(1, 2) @@ -238,7 +238,7 @@ if (point == yetAnotherPoint) { } // Point(1,2) and Point(2,2) are different. ``` -Hay mucho mas sobre las case classes que queremos presentar, y estamos convencidos de que te vas a enamorar de ellas. Las cubriremos en profundidad [mas adelante](case-classes.html). +Hay mucho mas sobre las case classes que queremos presentar, y estamos convencidos de que te vas a enamorar de ellas. Se tratan con más detalle [mas adelante](case-classes.html). ## Objetos @@ -271,7 +271,7 @@ Cubriremos los objetos en profundidad [mas adelante](singleton-objects.html). Los traits son tipos que contienen campos y métodos. Se pueden combinar múltiples traits. -Los traits se definen con la palabra clave `trait`. +Un trait se define usando la palabra reservada `trait`. ```tut trait Greeter { @@ -310,11 +310,11 @@ customGreeter.greet("Scala developer") // How are you, Scala developer? Aquí, `DefaultGreeter` extiende un solo trait, pero puede extender múltiples traits. -Cubriremos los traits en profundidad [mas adelante](traits.html). +Los `traits` se tratan con detalle [en otra página](traits.html). ## Método principal (Main Method) -El método principal (main) es el punto de entrada de un programa. La maquina virtual de java (JVM) requiere que el método principal sea llamado `main` y que tome un solo argumento: un arrray de Strings. +El método principal (main) es el punto donde comienza la ejecución de un programa en Scala. La máquina virtual de java (_Java Virtual Machine_ or JVM) requiere, para ejecutar un código Scala, que éste tenga un método principal llamado `main` cuyo único parámetro sea un arrray de Strings. Usando un objeto, puedes definir el método principal de la siguiente forma: From 6de4ca5c19c03f0d597798b58a6efe86fdb5c376 Mon Sep 17 00:00:00 2001 From: Gabriel Claramunt Date: Mon, 6 May 2019 00:07:54 -0300 Subject: [PATCH 0467/3075] review comments --- _es/tour/basics.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/_es/tour/basics.md b/_es/tour/basics.md index c8f45e7c5a..4147f63df1 100644 --- a/_es/tour/basics.md +++ b/_es/tour/basics.md @@ -24,13 +24,11 @@ Puedes ejecutar Scala en tu navegador con ScalaFiddle. Así, de manera fácil y sin preparación, puedes probar fragmentos de código Scala. -Many of the code examples in this documentation are also integrated with ScalaFiddle, so you -can directly experiment with them simply by clicking the Run-button. Muchos ejemplos de código en esta documentación están integrados con ScalaFiddle, y así puedes probarlos directamente solo con pulsar el botón "Run". ## Expresiones -En Scala todo es una expresión (cada sentencia "devuelve" un valor). +Las expresiones son sentencias computables. ```tut 1 + 1 @@ -105,7 +103,7 @@ println({ Una función es una expresión que acepta parámetros. -Se pueden definir funciones anónimas, por ejemplo, una que retorne x + 1 para x entero: +Una función se puede declarar anónima, sin nombre. Por ejemplo, ésta es una función que acepta un número entero `x`, y devuelve el resultado de incrementarlo `x+1`: ```tut (x: Int) => x + 1 @@ -244,7 +242,7 @@ Hay mucho mas sobre las case classes que queremos presentar, y estamos convencid Los objetos son instancias de una sola clase de su propia definición. Puedes pensar en ellos como singleton de sus propias clases -Puedes definir objectos con la palabra clave `object`. +Un objeto se define usando la palabra reservada `object`. ```tut object IdFactory { From 0e2289195e42a1fbaa136d6bcf010510e360a485 Mon Sep 17 00:00:00 2001 From: Ignasi Marimon-Clos Date: Mon, 6 May 2019 11:08:38 -0300 Subject: [PATCH 0468/3075] Apply suggestions from code review Co-Authored-By: gclaramunt --- _es/tour/basics.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/_es/tour/basics.md b/_es/tour/basics.md index 4147f63df1..c8155a77f8 100644 --- a/_es/tour/basics.md +++ b/_es/tour/basics.md @@ -12,7 +12,7 @@ next-page: unified-types previous-page: tour-of-scala --- -En esta página, cubriremos lo básico de Scala. +En esta página, practicaremos conceptos básicos de Scala. ## Probando Scala en el navegador @@ -59,10 +59,10 @@ Los resultados con nombre, como `x` en el ejemplo, son llamados valores. Referen Los valores no pueden ser reasignados. ```tut:fail -x = 3 // This does not compile. +x = 3 // Producirá un error de compilación. ``` -Los tipos de los valores pueden ser inferidos, pero también se pueden anotar explicitamente de la siguiente forma: +Los tipos de los valores pueden ser inferidos, pero también se pueden anotar explícitamente de la siguiente forma: ```tut val x: Int = 1 + 1 @@ -90,7 +90,7 @@ var x: Int = 1 + 1 Se pueden combinar expresiones rodeándolas con `{}` . A esto le llamamos un bloque. -El resultado de la ultima expresión del bloque es también el resultado total del bloque. +El resultado de la última expresión del bloque es también el resultado total del bloque. ```tut println({ @@ -120,7 +120,7 @@ println(addOne(1)) // 2 ``` {% endscalafiddle %} -Las funciones pueden tomar muchos parámetros. +Las funciones pueden tomar varios parámetros. {% scalafiddle %} ```tut @@ -149,9 +149,9 @@ println(add(1, 2)) // 3 ``` {% endscalafiddle %} -Observe que el tipo de retorno se declara _después_ de la lista de parámetros, y separado con dos puntos, e.g. `: Int`. +Observe que el tipo de retorno se declara _después_ de la lista de parámetros, y separado con dos puntos, p.ej. `: Int`. -Un método puede tener varias listas de parámetros +Un método puede tener varias listas de parámetros. {% scalafiddle %} ```tut @@ -179,7 +179,7 @@ def getSquareString(input: Double): String = { ``` La ultima expresión en el cuerpo del método es el valor de retorno del mismo. -(Scala tiene una palabra reservada `return`, pero se usa raramente, y no se aconseja usarla) +(Scala tiene una palabra reservada `return`, pero se usa raramente y no se aconseja usarla) ## Clases @@ -192,7 +192,7 @@ class Greeter(prefix: String, suffix: String) { } ``` -El método `greet` tiene un tipo de retorno `Unit`, que indica que el método no tiene nada significativo que devolver. Esto es similar al tipo `void` en C, C++, o Java. La diferencia con estos lenguajes es que, dado que en Scala toda expresión debe devuelvor un valor, se usa un tipo `Unit`, con un solo valor, que se escribe `()` y no lleva información. +El método `greet` tiene un tipo de retorno `Unit`, que indica que el método no tiene nada significativo que devolver. Esto es similar al tipo `void` en C, C++, o Java. La diferencia con estos lenguajes es que en Scala toda expresión debe devolver un valor. Se usa un tipo `Unit` que tiene con un solo valor que se escribe `()` y no lleva información. Se puede crear una instancia de una clase con la palabra reservada *new*. @@ -201,7 +201,7 @@ val greeter = new Greeter("Hello, ", "!") greeter.greet("Scala developer") // Hello, Scala developer! ``` -Las clases se tratan en profundidad [mas adelante](classes.html). +Las clases se tratan en profundidad [más adelante](classes.html). ## Case Classes @@ -236,11 +236,11 @@ if (point == yetAnotherPoint) { } // Point(1,2) and Point(2,2) are different. ``` -Hay mucho mas sobre las case classes que queremos presentar, y estamos convencidos de que te vas a enamorar de ellas. Se tratan con más detalle [mas adelante](case-classes.html). +Hay mucho más sobre las case classes que queremos presentar, y estamos convencidos de que te vas a enamorar de ellas. Se tratan con más detalle [mas adelante](case-classes.html). ## Objetos -Los objetos son instancias de una sola clase de su propia definición. Puedes pensar en ellos como singleton de sus propias clases +Los objetos son instancias de una sola clase de su propia definición. Puedes pensar en ellos como _singleton_ de sus propias clases. Un objeto se define usando la palabra reservada `object`. @@ -263,7 +263,7 @@ val newerId: Int = IdFactory.create() println(newerId) // 2 ``` -Cubriremos los objetos en profundidad [mas adelante](singleton-objects.html). +Cubriremos los objetos en profundidad [más adelante](singleton-objects.html). ## Traits @@ -287,7 +287,7 @@ trait Greeter { } ``` -También puedes extender traits con la palabra clave `extends` y sobrescribir una implementación con la palabra clave `override` . +También puedes extender traits con la palabra clave `extends` y sobrescribir una implementación con la palabra clave `override`. ```tut class DefaultGreeter extends Greeter From d17ca9078857b64ecb9f0e7479ddc9389bb8f1bc Mon Sep 17 00:00:00 2001 From: Gabriel Claramunt Date: Mon, 6 May 2019 13:46:57 -0300 Subject: [PATCH 0469/3075] Apply suggestions from code review Co-Authored-By: gclaramunt --- _es/tour/basics.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_es/tour/basics.md b/_es/tour/basics.md index c8155a77f8..d472a60ddf 100644 --- a/_es/tour/basics.md +++ b/_es/tour/basics.md @@ -62,7 +62,7 @@ Los valores no pueden ser reasignados. x = 3 // Producirá un error de compilación. ``` -Los tipos de los valores pueden ser inferidos, pero también se pueden anotar explícitamente de la siguiente forma: +Scala es capaz de inferir el tipo de un valor. Aun asi, también se puede indicar el tipo usando una anotación: ```tut val x: Int = 1 + 1 @@ -103,7 +103,7 @@ println({ Una función es una expresión que acepta parámetros. -Una función se puede declarar anónima, sin nombre. Por ejemplo, ésta es una función que acepta un número entero `x`, y devuelve el resultado de incrementarlo `x+1`: +Una función se puede declarar anónima, sin nombre. Por ejemplo, ésta es una función que acepta un número entero `x`, y devuelve el resultado de incrementarlo: ```tut (x: Int) => x + 1 @@ -192,7 +192,7 @@ class Greeter(prefix: String, suffix: String) { } ``` -El método `greet` tiene un tipo de retorno `Unit`, que indica que el método no tiene nada significativo que devolver. Esto es similar al tipo `void` en C, C++, o Java. La diferencia con estos lenguajes es que en Scala toda expresión debe devolver un valor. Se usa un tipo `Unit` que tiene con un solo valor que se escribe `()` y no lleva información. +El método `greet` tiene un tipo de retorno `Unit`, que indica que el método no tiene nada significativo que devolver. Esto es similar al tipo `void` en C, C++, o Java. La diferencia con estos lenguajes es que en Scala toda expresión debe devolver un valor. Por ello, se usa un tipo `Unit` que tiene con un solo valor que se escribe `()` y no lleva información. Se puede crear una instancia de una clase con la palabra reservada *new*. @@ -277,7 +277,7 @@ trait Greeter { } ``` -Los traits pueden también tener implementación por defecto. +Un `trait` también puede definit un método, o un valor, con una implementación por defecto. {% scalafiddle %} ```tut @@ -287,7 +287,7 @@ trait Greeter { } ``` -También puedes extender traits con la palabra clave `extends` y sobrescribir una implementación con la palabra clave `override`. +Un `trait` también puede extender otros traits, usando la palabra clave `extends`. Asimismo, en un `trait` se puede redefinir la implementación de un método heredado, usando la palabra reservada `override`. ```tut class DefaultGreeter extends Greeter From e70979eafa06e361b5353b6f91898c3fc80e1e72 Mon Sep 17 00:00:00 2001 From: Gabriel Claramunt Date: Mon, 6 May 2019 15:27:47 -0300 Subject: [PATCH 0470/3075] spellcheck --- _es/tour/basics.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_es/tour/basics.md b/_es/tour/basics.md index d472a60ddf..80977f061b 100644 --- a/_es/tour/basics.md +++ b/_es/tour/basics.md @@ -59,16 +59,16 @@ Los resultados con nombre, como `x` en el ejemplo, son llamados valores. Referen Los valores no pueden ser reasignados. ```tut:fail -x = 3 // Producirá un error de compilación. +x = 3 // This does not compile. ``` -Scala es capaz de inferir el tipo de un valor. Aun asi, también se puede indicar el tipo usando una anotación: +Scala es capaz de inferir el tipo de un valor. Aun así, también se puede indicar el tipo usando una anotación: ```tut val x: Int = 1 + 1 ``` -Noten como la declaración de tipo `Int` va después del identificador `x`. También necesitas un `:`. +Nótese que la anotación del tipo `Int` sigue al identificador `x` de la variable, separado por dos puntos `:`. ## Variables @@ -160,7 +160,7 @@ println(addThenMultiply(1, 2)(3)) // 9 ``` {% endscalafiddle %} -O ninguna lista de parametros. +O ninguna lista de parámetros. ```tut def name: String = System.getProperty("user.name") @@ -277,7 +277,7 @@ trait Greeter { } ``` -Un `trait` también puede definit un método, o un valor, con una implementación por defecto. +Un `trait` también puede definir un método, o un valor, con una implementación por defecto. {% scalafiddle %} ```tut From 9fd83799523ca0a3e56dbb8e2fef9f6076c9f858 Mon Sep 17 00:00:00 2001 From: Gabriel Claramunt Date: Tue, 7 May 2019 19:25:08 -0300 Subject: [PATCH 0471/3075] change next page link to target basics (#1325) --- _es/tour/tour-of-scala.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_es/tour/tour-of-scala.md b/_es/tour/tour-of-scala.md index 445b894c8d..14ef79cebc 100644 --- a/_es/tour/tour-of-scala.md +++ b/_es/tour/tour-of-scala.md @@ -9,7 +9,8 @@ partof: scala-tour num: 1 language: es -next-page: abstract-type-members +next-page: basics + --- Scala es un lenguaje de programación moderno multi-paradigma diseñado para expresar patrones de programación comunes de una forma concisa, elegante, y de tipado seguro. Integra fácilmente características de lenguajes orientados a objetos y funcionales. From 2d8f8e533e48b462680cf1e398d547721ed7c80f Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Fri, 10 May 2019 16:01:10 -0400 Subject: [PATCH 0472/3075] Add guidance on how to migrate scala.Seq --- _overviews/core/collections-migration-213.md | 28 ++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/_overviews/core/collections-migration-213.md b/_overviews/core/collections-migration-213.md index f58bad8e9f..7b8aed0c6f 100644 --- a/_overviews/core/collections-migration-213.md +++ b/_overviews/core/collections-migration-213.md @@ -10,6 +10,7 @@ how to cross-build projects with Scala 2.11 / 2.12 and 2.13. For an in-depth overview of the Scala 2.13 collections library, see the [collections guide]({{ site.baseurl }}/overviews/collections-2.13/introduction.html). The implementation details of the 2.13 collections are explained in the document [the architecture of Scala collections]({{ site.baseurl }}/overviews/core/architecture-of-scala-213-collections.html). The most important changes in the Scala 2.13 collections library are: + - `scala.Seq[+A]` is now an alias for `scala.collection.immutable.Seq[A]` (instead of `scala.collection.Seq[A]`). Note that this also changes the type of Scala varargs methods. - Transformation methods no longer have an implicit `CanBuildFrom` parameter. This makes the library easier to understand (in source code, Scaladoc, and IDE code completion). It also makes compiling user code more efficient. - The type hierarchy is simplified. `Traversable` no longer exists, only `Iterable`. - The `to[Collection]` method was replaced by the `to(Collection)` method. @@ -22,7 +23,6 @@ The most important changes in the Scala 2.13 collections library are: - Deprecated collections were removed (`MutableList`, `immutable.Stack`, others) - Parallel collections are now in a separate hierarchy in a [separate module](https://github.com/scala/scala-parallel-collections). - The `scala.jdk.StreamConverters` object provides extension methods to create (sequential or parallel) Java 8 streams for Scala collections. - - `scala.Seq` is now an alias for `scala.collection.immutable.Seq` (no longer `scala.collection.Seq`). Note that this also changes the type of Scala varargs methods. ## Tools for migrating and cross-building @@ -30,6 +30,31 @@ The [scala-collection-compat](https://github.com/scala/scala-collection-compat) The module also provides [migratrion rules](https://github.com/scala/scala-collection-compat#migration-tool) for [scalafix](https://scalacenter.github.io/scalafix/docs/users/installation.html) that can update a project's source code to work with the 2.13 collections library. +## scala.Seq migration + +In Scala 2.13 `scala.Seq[+A]` is an alias for `scala.collection.immutable.Seq[A]`, instead of `scala.collection.Seq[A]`. This change requires some planning depending on how your code is going to be used. + +If you're making an application, and simply migrating Scala 2.12 code base to 2.13, it might be ok to keep using `scala.Seq` in your code. + +If you're making a library intended to be used by other programmers, then using `scala.Seq` or vararg is going to be a breaking change in the API semantics. For example, if there was a function `def orderFood(order: Seq[Order]): Seq[Food]`, previously the library user would have been able to pass in an array of `Order`, but it won't work for 2.13. + +- if you cross build with Scala 2.12 and want to maintain the API semantics for 2.13 version of your library, or +- if your library users frequently uses mutable collections such as `Array` + +you can import `scala.collection.Seq` ("CSeq") explicitly in your code. + +~~~ scala +import scala.collection.Seq +~~~ + +In the future when your API is able to break the source compatibility, it might also make sense to migrate towards the `scala.collection.immutable.Seq` ("ISeq") for both Scala 2.12 and Scala 2.13. + +~~~ scala +import scala.collection.immutable.Seq +~~~ + +Note that in Scala 2.13 the sequence passed into a vararg as `orderFood(xs: _*)` must also be immutable. This is because the sequence passed into a vararg must conform to`scala.Seq` acoording to [Specification](https://www.scala-lang.org/files/archive/spec/2.12/06-expressions.html#function-applications). Thus if your API exposes varargs, it will be an unavoidable breaking change. This might affect Java interoperability. + ## What are the breaking changes? The following table summarizes the breaking changes. The "Automatic Migration Rule" column gives the name of the migration rule that can be used to automatically update old code to the new expected form. @@ -77,7 +102,6 @@ Some classes have been removed, made private or have no equivalent in the new de Other notable changes are: - `Iterable.partition` invokes `iterator` twice on non-strict collections and assumes it gets two iterators over the same elements. Strict subclasses override `partition` do perform only a single traversal - - `scala.Seq[+A]` is now `scala.collection.immutable.Seq[A]` (this also affects varargs methods). - Equality between collections is not anymore defined at the level of `Iterable`. It is defined separately in the `Set`, `Seq` and `Map` branches. Another consequence is that `Iterable` does not anymore have a `canEqual` method. - The new collections makes more use of overloading. You can find more information about the motivation behind this choice [here](http://scala-lang.org/blog/2017/05/30/tribulations-canbuildfrom.html). For instance, `Map.map` is overloaded: From 8178166fd0c7b3e6e7b5dfb025b76c469279aba1 Mon Sep 17 00:00:00 2001 From: eugene yokota Date: Fri, 10 May 2019 17:28:00 -0400 Subject: [PATCH 0473/3075] Update _overviews/core/collections-migration-213.md Co-Authored-By: Dale Wijnand <344610+dwijnand@users.noreply.github.com> --- _overviews/core/collections-migration-213.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_overviews/core/collections-migration-213.md b/_overviews/core/collections-migration-213.md index 7b8aed0c6f..e04c036d61 100644 --- a/_overviews/core/collections-migration-213.md +++ b/_overviews/core/collections-migration-213.md @@ -53,7 +53,7 @@ In the future when your API is able to break the source compatibility, it might import scala.collection.immutable.Seq ~~~ -Note that in Scala 2.13 the sequence passed into a vararg as `orderFood(xs: _*)` must also be immutable. This is because the sequence passed into a vararg must conform to`scala.Seq` acoording to [Specification](https://www.scala-lang.org/files/archive/spec/2.12/06-expressions.html#function-applications). Thus if your API exposes varargs, it will be an unavoidable breaking change. This might affect Java interoperability. +Note that in Scala 2.13 the sequence passed into as a varargs as `orderFood(xs: _*)` must also be immutable. This is because the sequence passed in as a varargs must conform to `scala.Seq` according to [SLS 6.6](https://www.scala-lang.org/files/archive/spec/2.12/06-expressions.html#function-applications). Thus, if your API exposes varargs it will be an unavoidable breaking change. This might affect Java interoperability. ## What are the breaking changes? @@ -260,4 +260,4 @@ Examples of libraries that cross-compile with separate source directories: To learn about differences when implementing custom collection types or operations, see the following documents: - [The architecture of Scala collections]({{ site.baseurl }}/overviews/core/architecture-of-scala-213-collections.html) - [Implementing custom collections]({{ site.baseurl }}/overviews/core/custom-collections.html) - - [Adding custom collection operations]({{ site.baseurl }}/overviews/core/custom-collection-operations.html) \ No newline at end of file + - [Adding custom collection operations]({{ site.baseurl }}/overviews/core/custom-collection-operations.html) From 54b38f7ee2ac71384741e7b2318eaa0f4f09d186 Mon Sep 17 00:00:00 2001 From: eugene yokota Date: Fri, 10 May 2019 17:32:25 -0400 Subject: [PATCH 0474/3075] Update _overviews/core/collections-migration-213.md Co-Authored-By: Dale Wijnand <344610+dwijnand@users.noreply.github.com> --- _overviews/core/collections-migration-213.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/core/collections-migration-213.md b/_overviews/core/collections-migration-213.md index e04c036d61..ac2be9d9d3 100644 --- a/_overviews/core/collections-migration-213.md +++ b/_overviews/core/collections-migration-213.md @@ -34,7 +34,7 @@ The module also provides [migratrion rules](https://github.com/scala/scala-colle In Scala 2.13 `scala.Seq[+A]` is an alias for `scala.collection.immutable.Seq[A]`, instead of `scala.collection.Seq[A]`. This change requires some planning depending on how your code is going to be used. -If you're making an application, and simply migrating Scala 2.12 code base to 2.13, it might be ok to keep using `scala.Seq` in your code. +If you're making an application, and simply migrating a Scala 2.12 code base to 2.13, it might be ok to keep using `scala.Seq` in your code. If you're making a library intended to be used by other programmers, then using `scala.Seq` or vararg is going to be a breaking change in the API semantics. For example, if there was a function `def orderFood(order: Seq[Order]): Seq[Food]`, previously the library user would have been able to pass in an array of `Order`, but it won't work for 2.13. From 6c566237690ef8948d619fea97ab91e96cbc18fc Mon Sep 17 00:00:00 2001 From: eugene yokota Date: Fri, 10 May 2019 17:32:39 -0400 Subject: [PATCH 0475/3075] Update _overviews/core/collections-migration-213.md Co-Authored-By: Dale Wijnand <344610+dwijnand@users.noreply.github.com> --- _overviews/core/collections-migration-213.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/core/collections-migration-213.md b/_overviews/core/collections-migration-213.md index ac2be9d9d3..7b4a59f124 100644 --- a/_overviews/core/collections-migration-213.md +++ b/_overviews/core/collections-migration-213.md @@ -36,7 +36,7 @@ In Scala 2.13 `scala.Seq[+A]` is an alias for `scala.collection.immutable.Seq[A] If you're making an application, and simply migrating a Scala 2.12 code base to 2.13, it might be ok to keep using `scala.Seq` in your code. -If you're making a library intended to be used by other programmers, then using `scala.Seq` or vararg is going to be a breaking change in the API semantics. For example, if there was a function `def orderFood(order: Seq[Order]): Seq[Food]`, previously the library user would have been able to pass in an array of `Order`, but it won't work for 2.13. +If you're making a library intended to be used by other programmers, then using `scala.Seq` or varargs is going to be a breaking change in the API semantics. For example, if there was a function `def orderFood(order: Seq[Order]): Seq[Food]`, previously the library user would have been able to pass in an array of `Order`, but it won't work for 2.13. - if you cross build with Scala 2.12 and want to maintain the API semantics for 2.13 version of your library, or - if your library users frequently uses mutable collections such as `Array` From 66fb063a96e63630e709257e807219d53a6d5ef1 Mon Sep 17 00:00:00 2001 From: "Aaron S. Hawley" Date: Thu, 16 May 2019 22:52:32 -0400 Subject: [PATCH 0476/3075] Add redirect for partest-guide (#1329) https://github.com/scala/scala-partest --- _overviews/tutorials/partest-guide.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 _overviews/tutorials/partest-guide.md diff --git a/_overviews/tutorials/partest-guide.md b/_overviews/tutorials/partest-guide.md new file mode 100644 index 0000000000..36fa8c74c7 --- /dev/null +++ b/_overviews/tutorials/partest-guide.md @@ -0,0 +1,6 @@ +--- +layout: inner-page-no-masthead +sitemap: false +permalink: /tutorials/partest-guide.html +redirect_to: https://github.com/scala/scala-partest +--- From 017fef76e43a45fcd01d42f5a6558c0b48e23f31 Mon Sep 17 00:00:00 2001 From: Suyash Date: Sat, 18 May 2019 08:44:57 +0400 Subject: [PATCH 0477/3075] Update getting-started-with-scala-in-intellij.md updating doc for adding scala framework support addition which was missing earlier --- .../getting-started-with-scala-in-intellij.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting-started-intellij-track/getting-started-with-scala-in-intellij.md b/getting-started-intellij-track/getting-started-with-scala-in-intellij.md index f6cd28b50a..b6517c06bd 100644 --- a/getting-started-intellij-track/getting-started-with-scala-in-intellij.md +++ b/getting-started-intellij-track/getting-started-with-scala-in-intellij.md @@ -36,7 +36,7 @@ take a few minutes but subsequent projects can use the same SDK. ## Writing code 1. On the **Project** pane on the left, right-click `src` and select -**New** => **Scala class**. +**New** => **Scala class**. If you don't see **Scala class**, right-click on **HelloWorld** and click on **Add Framework Support...**, select **Scala** and proceed. If you see **Error: library is not specified**, you can either click donload button, or select the library path manually. 1. Name the class `Hello` and change the **Kind** to `object`. 1. Change the code in the class to the following: From 8025fe3685a7a66c8f329c4ffa746fbc880ad0f0 Mon Sep 17 00:00:00 2001 From: Suyash Date: Sun, 19 May 2019 11:56:00 +0400 Subject: [PATCH 0478/3075] Update getting-started-with-scala-in-intellij.md Fixing typo. --- .../getting-started-with-scala-in-intellij.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/getting-started-intellij-track/getting-started-with-scala-in-intellij.md b/getting-started-intellij-track/getting-started-with-scala-in-intellij.md index b6517c06bd..730f2e7f36 100644 --- a/getting-started-intellij-track/getting-started-with-scala-in-intellij.md +++ b/getting-started-intellij-track/getting-started-with-scala-in-intellij.md @@ -36,7 +36,7 @@ take a few minutes but subsequent projects can use the same SDK. ## Writing code 1. On the **Project** pane on the left, right-click `src` and select -**New** => **Scala class**. If you don't see **Scala class**, right-click on **HelloWorld** and click on **Add Framework Support...**, select **Scala** and proceed. If you see **Error: library is not specified**, you can either click donload button, or select the library path manually. +**New** => **Scala class**. If you don't see **Scala class**, right-click on **HelloWorld** and click on **Add Framework Support...**, select **Scala** and proceed. If you see **Error: library is not specified**, you can either click download button, or select the library path manually. 1. Name the class `Hello` and change the **Kind** to `object`. 1. Change the code in the class to the following: From 9afd159f5556ad9a772e8a264e000d30d910c168 Mon Sep 17 00:00:00 2001 From: Akhtyam Sakaev <3930435+asakaev@users.noreply.github.com> Date: Sat, 18 May 2019 01:38:15 +0300 Subject: [PATCH 0479/3075] refine pattern-matching.md --- _tour/pattern-matching.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_tour/pattern-matching.md b/_tour/pattern-matching.md index b5f9e37d46..20ca742c70 100644 --- a/_tour/pattern-matching.md +++ b/_tour/pattern-matching.md @@ -28,19 +28,19 @@ x match { case 0 => "zero" case 1 => "one" case 2 => "two" - case _ => "many" + case _ => "other" } ``` -The `val x` above is a random integer between 0 and 10. `x` becomes the left operand of the `match` operator and on the right is an expression with four cases. The last case `_` is a "catch all" case for any number greater than 2. Cases are also called _alternatives_. +The `val x` above is a random integer between 0 and 10. `x` becomes the left operand of the `match` operator and on the right is an expression with four cases. The last case `_` is a "catch all" case for any other possible `Int` values. Cases are also called _alternatives_. Match expressions have a value. ```tut def matchTest(x: Int): String = x match { case 1 => "one" case 2 => "two" - case _ => "many" + case _ => "other" } -matchTest(3) // many +matchTest(3) // other matchTest(1) // one ``` This match expression has a type String because all of the cases return String. Therefore, the function `matchTest` returns a String. From 2b4de2d746a2ffb8547298897d585c94b711f508 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 20 May 2019 18:17:11 -0400 Subject: [PATCH 0480/3075] reflect review comments --- _overviews/core/collections-migration-213.md | 66 ++++++++++++++++++-- 1 file changed, 60 insertions(+), 6 deletions(-) diff --git a/_overviews/core/collections-migration-213.md b/_overviews/core/collections-migration-213.md index 7b4a59f124..f877849115 100644 --- a/_overviews/core/collections-migration-213.md +++ b/_overviews/core/collections-migration-213.md @@ -32,29 +32,83 @@ The module also provides [migratrion rules](https://github.com/scala/scala-colle ## scala.Seq migration -In Scala 2.13 `scala.Seq[+A]` is an alias for `scala.collection.immutable.Seq[A]`, instead of `scala.collection.Seq[A]`. This change requires some planning depending on how your code is going to be used. - -If you're making an application, and simply migrating a Scala 2.12 code base to 2.13, it might be ok to keep using `scala.Seq` in your code. +In Scala 2.13 `scala.Seq[+A]` is an alias for `scala.collection.immutable.Seq[A]` ("ISeq"), instead of `scala.collection.Seq[A]` ("CSeq"). This change requires some planning depending on how your code is going to be used. If you're making a library intended to be used by other programmers, then using `scala.Seq` or varargs is going to be a breaking change in the API semantics. For example, if there was a function `def orderFood(order: Seq[Order]): Seq[Food]`, previously the library user would have been able to pass in an array of `Order`, but it won't work for 2.13. - if you cross build with Scala 2.12 and want to maintain the API semantics for 2.13 version of your library, or - if your library users frequently uses mutable collections such as `Array` -you can import `scala.collection.Seq` ("CSeq") explicitly in your code. +you can import collection Seq explicitly in your code. ~~~ scala import scala.collection.Seq + +object FoodToGo { + def orderFood(order: Seq[Order]): Seq[Food] +} +~~~ + +Note that this might still break the source compatibility if `scala.Seq` (or just `Seq`) appears in the source code. + +~~~ scala +val food: Seq[Food] = FoodToGo.orderFood(order) // won't compile ~~~ -In the future when your API is able to break the source compatibility, it might also make sense to migrate towards the `scala.collection.immutable.Seq` ("ISeq") for both Scala 2.12 and Scala 2.13. +Since `Seq`, an alias for ISeq in 2.13, is narrower than CSeq, the above code will no longer compile. One workaround would be to ask your users to add `toSeq`, which returns ISeq. ~~~ scala -import scala.collection.immutable.Seq +val food: Seq[Food] = FoodToGo.orderFood(order).toSeq // add .toSeq ~~~ +Another workaround might be to accept CSeq, but return ISeq. + +~~~ scala +import scala.collection.{ Seq => CSeq } +import scala.collection.immutable.{ Seq => ISeq } + +object FoodToGo { + def orderFood(order: CSeq[Order]): ISeq[Food] +} +~~~ + +In the future when your API is able to break the source compatibility, it might also make sense to migrate towards ISeq for both Scala 2.12 and Scala 2.13. + +~~~ scala +import scala.collection.immutable.{ Seq => ISeq } + +object FoodToGo { + def orderFood(order: ISeq[Order]): ISeq[Food] +} +~~~ + +Similarly, if you're making an end-user application, unifying to CSeq might be the easier and safer initial path especially for a larger and complex code base. Switching to ISeq will be a more advanced refactoring. + Note that in Scala 2.13 the sequence passed into as a varargs as `orderFood(xs: _*)` must also be immutable. This is because the sequence passed in as a varargs must conform to `scala.Seq` according to [SLS 6.6](https://www.scala-lang.org/files/archive/spec/2.12/06-expressions.html#function-applications). Thus, if your API exposes varargs it will be an unavoidable breaking change. This might affect Java interoperability. +### Masking scala.Seq + +To use the compiler to bad the use of plain `Seq`, you can declare your own `Seq` to mask `scala.Seq`. + +~~~ scala +package example + +import scala.annotation.compileTimeOnly + +/** + * In Scala 2.13, scala.Seq moved from scala.collection.Seq to scala.collection.immutable.Seq. + * In this code base, we'll require you to name ISeq or CSeq. + * + * import scala.collection.{ Seq => CSeq } + * import scala.collection.immutable.{ Seq => ISeq } + * + * This Seq trait is a dummy type to prevent the use of `Seq`. + */ +@compileTimeOnly("Use ISeq or CSeq") private[example] trait Seq[A1, F1[A2], A3] +~~~ + +This might be useful during the transition period where you have to remember to import CSeq. + ## What are the breaking changes? The following table summarizes the breaking changes. The "Automatic Migration Rule" column gives the name of the migration rule that can be used to automatically update old code to the new expected form. From cc9b455f6d43d30aa67220e33dc598b381ad3f07 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Mon, 20 May 2019 18:23:35 -0400 Subject: [PATCH 0481/3075] scala.IndexedSeq too --- _overviews/core/collections-migration-213.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/_overviews/core/collections-migration-213.md b/_overviews/core/collections-migration-213.md index f877849115..730ddb34b9 100644 --- a/_overviews/core/collections-migration-213.md +++ b/_overviews/core/collections-migration-213.md @@ -11,6 +11,7 @@ For an in-depth overview of the Scala 2.13 collections library, see the [collect The most important changes in the Scala 2.13 collections library are: - `scala.Seq[+A]` is now an alias for `scala.collection.immutable.Seq[A]` (instead of `scala.collection.Seq[A]`). Note that this also changes the type of Scala varargs methods. + - `scala.IndexedSeq[+A]` is now an alias for `scala.collection.immutable.IndexedSeq[A]` (instead of `scala.collection.IndexedSeq[A]`). - Transformation methods no longer have an implicit `CanBuildFrom` parameter. This makes the library easier to understand (in source code, Scaladoc, and IDE code completion). It also makes compiling user code more efficient. - The type hierarchy is simplified. `Traversable` no longer exists, only `Iterable`. - The `to[Collection]` method was replaced by the `to(Collection)` method. @@ -30,11 +31,11 @@ The [scala-collection-compat](https://github.com/scala/scala-collection-compat) The module also provides [migratrion rules](https://github.com/scala/scala-collection-compat#migration-tool) for [scalafix](https://scalacenter.github.io/scalafix/docs/users/installation.html) that can update a project's source code to work with the 2.13 collections library. -## scala.Seq migration +## scala.Seq and scala.IndexedSeq migration -In Scala 2.13 `scala.Seq[+A]` is an alias for `scala.collection.immutable.Seq[A]` ("ISeq"), instead of `scala.collection.Seq[A]` ("CSeq"). This change requires some planning depending on how your code is going to be used. +In Scala 2.13 `scala.Seq[+A]` is an alias for `scala.collection.immutable.Seq[A]` ("ISeq"), instead of `scala.collection.Seq[A]` ("CSeq"). Similarly, `scala.IndexedSeq[+A]` is an alias for `scala.collection.immutable.IndexedSeq[A]`. These changes require some planning depending on how your code is going to be used. -If you're making a library intended to be used by other programmers, then using `scala.Seq` or varargs is going to be a breaking change in the API semantics. For example, if there was a function `def orderFood(order: Seq[Order]): Seq[Food]`, previously the library user would have been able to pass in an array of `Order`, but it won't work for 2.13. +If you're making a library intended to be used by other programmers, then using `scala.Seq`, `scala.IndexedSeq`, or vararg is going to be a breaking change in the API semantics. For example, if there was a function `def orderFood(order: Seq[Order]): Seq[Food]`, previously the library user would have been able to pass in an array of `Order`, but it won't work for 2.13. - if you cross build with Scala 2.12 and want to maintain the API semantics for 2.13 version of your library, or - if your library users frequently uses mutable collections such as `Array` @@ -105,6 +106,17 @@ import scala.annotation.compileTimeOnly * This Seq trait is a dummy type to prevent the use of `Seq`. */ @compileTimeOnly("Use ISeq or CSeq") private[example] trait Seq[A1, F1[A2], A3] + +/** + * In Scala 2.13, scala.IndexedSeq moved from scala.collection.IndexedSeq to scala.collection.immutable.IndexedSeq. + * In this code base, we'll require you to name ISeq or CSeq. + * + * import scala.collection.{ IndexedSeq => CIndexedSeq } + * import scala.collection.immutable.{ IndexedSeq => IIndexedSeq } + * + * This IndexedSeq trait is a dummy type to prevent the use of `IndexedSeq`. + */ +@compileTimeOnly("Use IIndexedSeq or CIndexedSeq") private[example] trait IndexedSeq[A1, F1[A2], A3] ~~~ This might be useful during the transition period where you have to remember to import CSeq. From a0a7b9babd80592fe1ae8d01e190f6ddabe0fe11 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Mon, 20 May 2019 19:36:39 -0700 Subject: [PATCH 0482/3075] RC2 is here --- api/all.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/api/all.md b/api/all.md index 50c5bea6bc..d2caf5f5a7 100644 --- a/api/all.md +++ b/api/all.md @@ -28,10 +28,10 @@ includeTOC: true ## Prereleases -* Scala 2.13.0-RC1 - * [Library API](https://www.scala-lang.org/api/2.13.0-RC1/) - * [Compiler API](https://www.scala-lang.org/api/2.13.0-RC1/scala-compiler/scala/) - * [Reflection API](https://www.scala-lang.org/api/2.13.0-RC1/scala-reflect/scala/reflect/) +* Scala 2.13.0-RC2 + * [Library API](https://www.scala-lang.org/api/2.13.0-RC2/) + * [Compiler API](https://www.scala-lang.org/api/2.13.0-RC2/scala-compiler/scala/) + * [Reflection API](https://www.scala-lang.org/api/2.13.0-RC2/scala-reflect/scala/reflect/) ## Nightly builds From e498da2ff78db946b41270999cb327177c150356 Mon Sep 17 00:00:00 2001 From: Noah Rosamilia Date: Tue, 21 May 2019 10:22:10 -0400 Subject: [PATCH 0483/3075] Fix typo in implicit-parameters.md --- _tour/implicit-parameters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_tour/implicit-parameters.md b/_tour/implicit-parameters.md index 43befb04e7..5f2c181491 100644 --- a/_tour/implicit-parameters.md +++ b/_tour/implicit-parameters.md @@ -56,7 +56,7 @@ object ImplicitTest { To show how implicit parameters work, we first define monoids `stringMonoid` and `intMonoid` for strings and integers, respectively. The `implicit` keyword indicates that the corresponding object can be used implicitly. -The method `sum` takes a `List[A]` and returns an `A`, which takes the initial `A` from `unit`, and combines each next `A` in the list to that with the `add` method. Making the parameter `m` implicit here means we only have to provide the `xs` parameter when we call the method if Scala can find a an implict `Monoid[A]` to use for the implicit `m` parameter. +The method `sum` takes a `List[A]` and returns an `A`, which takes the initial `A` from `unit`, and combines each next `A` in the list to that with the `add` method. Making the parameter `m` implicit here means we only have to provide the `xs` parameter when we call the method if Scala can find an implict `Monoid[A]` to use for the implicit `m` parameter. In our `main` method we call `sum` twice, and only provide the `xs` parameter. Scala will now look for an implicit in the scope mentioned above. The first call to `sum` passes a `List[Int]` for `xs`, which means that `A` is `Int`. The implicit parameter list with `m` is left out, so Scala will look for an implicit of type `Monoid[Int]`. The first lookup rule reads From 182cc3f73799e5537404593b20f43aa81340334c Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Tue, 21 May 2019 21:03:08 +0200 Subject: [PATCH 0484/3075] Fix typo --- _tour/implicit-parameters.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_tour/implicit-parameters.md b/_tour/implicit-parameters.md index 5f2c181491..aeb43361b4 100644 --- a/_tour/implicit-parameters.md +++ b/_tour/implicit-parameters.md @@ -56,7 +56,7 @@ object ImplicitTest { To show how implicit parameters work, we first define monoids `stringMonoid` and `intMonoid` for strings and integers, respectively. The `implicit` keyword indicates that the corresponding object can be used implicitly. -The method `sum` takes a `List[A]` and returns an `A`, which takes the initial `A` from `unit`, and combines each next `A` in the list to that with the `add` method. Making the parameter `m` implicit here means we only have to provide the `xs` parameter when we call the method if Scala can find an implict `Monoid[A]` to use for the implicit `m` parameter. +The method `sum` takes a `List[A]` and returns an `A`, which takes the initial `A` from `unit`, and combines each next `A` in the list to that with the `add` method. Making the parameter `m` implicit here means we only have to provide the `xs` parameter when we call the method if Scala can find an implicit `Monoid[A]` to use for the implicit `m` parameter. In our `main` method we call `sum` twice, and only provide the `xs` parameter. Scala will now look for an implicit in the scope mentioned above. The first call to `sum` passes a `List[Int]` for `xs`, which means that `A` is `Int`. The implicit parameter list with `m` is left out, so Scala will look for an implicit of type `Monoid[Int]`. The first lookup rule reads From 83173abf49f8dc02217c25b8564c0ce609ff0f74 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 21 May 2019 09:55:08 +0100 Subject: [PATCH 0485/3075] Tweak Seq migration guide --- _overviews/core/collections-migration-213.md | 117 +++++++++++++------ 1 file changed, 81 insertions(+), 36 deletions(-) diff --git a/_overviews/core/collections-migration-213.md b/_overviews/core/collections-migration-213.md index 730ddb34b9..71b9cbf815 100644 --- a/_overviews/core/collections-migration-213.md +++ b/_overviews/core/collections-migration-213.md @@ -31,65 +31,106 @@ The [scala-collection-compat](https://github.com/scala/scala-collection-compat) The module also provides [migratrion rules](https://github.com/scala/scala-collection-compat#migration-tool) for [scalafix](https://scalacenter.github.io/scalafix/docs/users/installation.html) that can update a project's source code to work with the 2.13 collections library. -## scala.Seq and scala.IndexedSeq migration +## scala.Seq, varargs and scala.IndexedSeq migration -In Scala 2.13 `scala.Seq[+A]` is an alias for `scala.collection.immutable.Seq[A]` ("ISeq"), instead of `scala.collection.Seq[A]` ("CSeq"). Similarly, `scala.IndexedSeq[+A]` is an alias for `scala.collection.immutable.IndexedSeq[A]`. These changes require some planning depending on how your code is going to be used. +In Scala 2.13 `scala.Seq[+A]` is an alias for `scala.collection.immutable.Seq[A]`, instead of `scala.collection.Seq[A]`, and `scala.IndexedSeq[+A]` is an alias for `scala.collection.immutable.IndexedSeq[A]`. These changes require some planning depending on how your code is going to be used. -If you're making a library intended to be used by other programmers, then using `scala.Seq`, `scala.IndexedSeq`, or vararg is going to be a breaking change in the API semantics. For example, if there was a function `def orderFood(order: Seq[Order]): Seq[Food]`, previously the library user would have been able to pass in an array of `Order`, but it won't work for 2.13. +The change in definition of `scala.Seq` also has the effect of making the type of varargs parameters immutable sequences, due to [SLS 6.6][], so in +a method such as `orderFood(xs: _*)` the varargs parameter `xs` must be an immutable sequence. -- if you cross build with Scala 2.12 and want to maintain the API semantics for 2.13 version of your library, or -- if your library users frequently uses mutable collections such as `Array` +[SLS 6.6]: https://www.scala-lang.org/files/archive/spec/2.12/06-expressions.html#function-applications -you can import collection Seq explicitly in your code. +Therefore any method signature in Scala 2.13 which includes `scala.Seq`, varargs, or `scala.IndexedSeq` is going +to have a breaking change in API semantics (as the immutable sequence types require more — immutability — than the +not-immutable types). For example, users of a method like `def orderFood(order: Seq[Order]): Seq[Food]` would +previously have been able to pass in an `ArrayBuffer` of `Order`, but cannot in 2.13. + +### Migrating varargs + +The change for varargs is unavoidable, as you cannot change the type used at definition site. The options +available for migrating the usage sites are the following: + +- change the value to already be an immutable sequence, which allows for direct varargs usage: `xs: _*`, +- change the value to be an immutable sequence on the fly by calling `.toSeq`: `xs.toSeq: _*`, which will only + copy data if the sequence wasn't already immutable +- use `scala.collection.immutable.ArraySeq.unsafeWrapArray` to wrap your array and avoid copying, but see its + scaladoc + +### Option 1: migrate back to scala.collection.Seq + +The first, in some ways simplest, migration strategy for all non-varargs usages of `scala.Seq` is to replace +them with `scala.collection.Seq` (and require users to call `.toSeq` or `unsafeWrapArray` when passing such +sequences to varargs methods). + +We recommend using `import scala.collection`/`import scala.collection.immutable` and +`collection.Seq`/`immutable.Seq`. + +We recommend against using `import scala.collection.Seq`, which shadows the automatically imported `scala.Seq`, +because even if it's a oneline change it causes name confusion. For code generation or macros the safest option +is using the fully-qualified `_root_.scala.collection.Seq`. + +As an example, the migration would look something like this: ~~~ scala -import scala.collection.Seq +import scala.collection object FoodToGo { - def orderFood(order: Seq[Order]): Seq[Food] + def orderFood(order: collection.Seq[Order]): collection.Seq[Food] } ~~~ -Note that this might still break the source compatibility if `scala.Seq` (or just `Seq`) appears in the source code. +However users of this code in Scala 2.13 would also have to migrate, as the result type is source-incompatible +with any `scala.Seq` (or just `Seq`) usage in their code: ~~~ scala val food: Seq[Food] = FoodToGo.orderFood(order) // won't compile ~~~ -Since `Seq`, an alias for ISeq in 2.13, is narrower than CSeq, the above code will no longer compile. One workaround would be to ask your users to add `toSeq`, which returns ISeq. +The simplest workaround is to ask your users to call `.toSeq` on the result which will return an immutable Seq, +and only copy data if the sequence wasn't immutable: ~~~ scala val food: Seq[Food] = FoodToGo.orderFood(order).toSeq // add .toSeq ~~~ -Another workaround might be to accept CSeq, but return ISeq. +### Option 2: use scala.collection.Seq for parameters and scala.collection.immutable.Seq for result types + +The second, intermediate, migration strategy would be to change all methods to accept not-immutable Seq but +return immutable Seq, following the [robustness principle][] (also known as "Postel's law"): + +[robustness principle]: https://en.wikipedia.org/wiki/Robustness_principle ~~~ scala -import scala.collection.{ Seq => CSeq } -import scala.collection.immutable.{ Seq => ISeq } +import scala.collection +import scala.collection.immutable object FoodToGo { - def orderFood(order: CSeq[Order]): ISeq[Food] + def orderFood(order: collection.Seq[Order]): immutable.Seq[Food] } ~~~ -In the future when your API is able to break the source compatibility, it might also make sense to migrate towards ISeq for both Scala 2.12 and Scala 2.13. +### Option 3: use immutable sequences + +The third migration strategy is to change your API to use immutable sequences for both parameter and result +types. When cross-building your library for Scala 2.12 and 2.13 this could either mean: + +- continuing to use `scala.Seq` which means it stays source and binary-compatible in 2.12, but would have to + have immutable sequence semantics (but that might already be the case). +- switch to explicitly using immutable Seq in both Scala 2.12 and 2.13, which means breaking source, binary and + (possibly) semantic compatibility in 2.12: ~~~ scala -import scala.collection.immutable.{ Seq => ISeq } +import scala.collection.immutable object FoodToGo { - def orderFood(order: ISeq[Order]): ISeq[Food] + def orderFood(order: immutable.Seq[Order]): immutable.Seq[Food] } ~~~ -Similarly, if you're making an end-user application, unifying to CSeq might be the easier and safer initial path especially for a larger and complex code base. Switching to ISeq will be a more advanced refactoring. - -Note that in Scala 2.13 the sequence passed into as a varargs as `orderFood(xs: _*)` must also be immutable. This is because the sequence passed in as a varargs must conform to `scala.Seq` according to [SLS 6.6](https://www.scala-lang.org/files/archive/spec/2.12/06-expressions.html#function-applications). Thus, if your API exposes varargs it will be an unavoidable breaking change. This might affect Java interoperability. - -### Masking scala.Seq +### Shadowing scala.Seq and scala.IndexedSeq -To use the compiler to bad the use of plain `Seq`, you can declare your own `Seq` to mask `scala.Seq`. +You maybe be interested in entirely banning plain `Seq` usage. You can use the compiler to do so by declaring +your own package-level (and package private) `Seq` type which will mask `scala.Seq`. ~~~ scala package example @@ -97,29 +138,33 @@ package example import scala.annotation.compileTimeOnly /** - * In Scala 2.13, scala.Seq moved from scala.collection.Seq to scala.collection.immutable.Seq. - * In this code base, we'll require you to name ISeq or CSeq. + * In Scala 2.13, `scala.Seq` changed from aliasing `scala.collection.Seq` to aliasing + * `scala.collection.immutable.Seq`. In this code base usage of unqualified `Seq` is banned: use + * `immutable.Seq` or `collection.Seq` instead. * - * import scala.collection.{ Seq => CSeq } - * import scala.collection.immutable.{ Seq => ISeq } + * import scala.collection + * import scala.collection.immutable * - * This Seq trait is a dummy type to prevent the use of `Seq`. + * This `Seq` trait is a dummy type to prevent the use of `Seq`. */ -@compileTimeOnly("Use ISeq or CSeq") private[example] trait Seq[A1, F1[A2], A3] +@compileTimeOnly("Use immutable.Seq or collection.Seq") +private[example] trait Seq[A1] /** - * In Scala 2.13, scala.IndexedSeq moved from scala.collection.IndexedSeq to scala.collection.immutable.IndexedSeq. - * In this code base, we'll require you to name ISeq or CSeq. + * In Scala 2.13, `scala.IndexedSeq` changed from aliasing `scala.collection.IndexedSeq` to aliasing + * `scala.collection.immutable.IndexedSeq`. In this code base usage of unqualified `IndexedSeq` is + * banned: use `immutable.IndexedSeq` or `collection.IndexedSeq`. * - * import scala.collection.{ IndexedSeq => CIndexedSeq } - * import scala.collection.immutable.{ IndexedSeq => IIndexedSeq } + * import scala.collection + * import scala.collection.immutable * - * This IndexedSeq trait is a dummy type to prevent the use of `IndexedSeq`. + * This `IndexedSeq` trait is a dummy type to prevent the use of `IndexedSeq`. */ -@compileTimeOnly("Use IIndexedSeq or CIndexedSeq") private[example] trait IndexedSeq[A1, F1[A2], A3] +@compileTimeOnly("Use immutable.IndexedSeq or collection.IndexedSeq") +private[example] trait IndexedSeq[A1] ~~~ -This might be useful during the transition period where you have to remember to import CSeq. +This might be useful during the migration to catch usages of unqualified `Seq` and `IndexedSeq`. ## What are the breaking changes? From a527db979319fd7689897661d5443ca81514c280 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 23 May 2019 11:33:21 +0000 Subject: [PATCH 0486/3075] Bump nokogiri from 1.8.4 to 1.8.5 Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.8.4 to 1.8.5. - [Release notes](https://github.com/sparklemotion/nokogiri/releases) - [Changelog](https://github.com/sparklemotion/nokogiri/blob/master/CHANGELOG.md) - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.8.4...v1.8.5) --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4157511c7d..de18a3160a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -61,7 +61,7 @@ GEM mercenary (0.3.6) mini_portile2 (2.3.0) minitest (5.11.3) - nokogiri (1.8.4) + nokogiri (1.8.5) mini_portile2 (~> 2.3.0) parallel (1.12.1) pathutil (0.16.1) From 3b4357de9f9569257d793330cbf5b49d9caea9e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" Date: Thu, 23 May 2019 11:33:47 +0000 Subject: [PATCH 0487/3075] Bump jekyll from 3.8.3 to 3.8.5 Bumps [jekyll](https://github.com/jekyll/jekyll) from 3.8.3 to 3.8.5. - [Release notes](https://github.com/jekyll/jekyll/releases) - [Changelog](https://github.com/jekyll/jekyll/blob/master/History.markdown) - [Commits](https://github.com/jekyll/jekyll/compare/v3.8.3...v3.8.5) --- Gemfile.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 4157511c7d..16afcdf020 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -6,18 +6,18 @@ GEM i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.5.2) + addressable (2.6.0) public_suffix (>= 2.0.2, < 4.0) colorator (1.1.0) colorize (0.8.1) - concurrent-ruby (1.0.5) + concurrent-ruby (1.1.5) em-websocket (0.5.1) eventmachine (>= 0.12.9) http_parser.rb (~> 0.6.0) ethon (0.11.0) ffi (>= 1.3.0) eventmachine (1.2.7) - ffi (1.9.25) + ffi (1.11.1) forwardable-extended (2.6.0) html-proofer (3.9.1) activesupport (>= 4.2, < 6.0) @@ -31,7 +31,7 @@ GEM http_parser.rb (0.6.0) i18n (0.9.5) concurrent-ruby (~> 1.0) - jekyll (3.8.3) + jekyll (3.8.5) addressable (~> 2.4) colorator (~> 1.0) em-websocket (~> 0.5) @@ -50,10 +50,10 @@ GEM sass (~> 3.4) jekyll-scalafiddle (1.0.1) jekyll (~> 3.0) - jekyll-watch (2.0.0) + jekyll-watch (2.2.1) listen (~> 3.0) kramdown (1.17.0) - liquid (4.0.0) + liquid (4.0.3) listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) @@ -64,16 +64,16 @@ GEM nokogiri (1.8.4) mini_portile2 (~> 2.3.0) parallel (1.12.1) - pathutil (0.16.1) + pathutil (0.16.2) forwardable-extended (~> 2.6) - public_suffix (3.0.2) + public_suffix (3.0.3) rb-fsevent (0.10.3) - rb-inotify (0.9.10) - ffi (>= 0.5.0, < 2) - rouge (3.1.1) + rb-inotify (0.10.0) + ffi (~> 1.0) + rouge (3.3.0) ruby_dep (1.5.0) - safe_yaml (1.0.4) - sass (3.5.7) + safe_yaml (1.0.5) + sass (3.7.4) sass-listen (~> 4.0.0) sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) From debd78f1d8d123c3b9da4c89027638728fbc42c2 Mon Sep 17 00:00:00 2001 From: Filipe Regadas Date: Mon, 27 May 2019 18:29:35 -0400 Subject: [PATCH 0488/3075] Fix invalid universe import --- _overviews/quasiquotes/lifting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/quasiquotes/lifting.md b/_overviews/quasiquotes/lifting.md index 2c6126a789..c28082b716 100644 --- a/_overviews/quasiquotes/lifting.md +++ b/_overviews/quasiquotes/lifting.md @@ -49,7 +49,7 @@ To define tree representation for your own data type just provide an implicit in package points - import scala.universe._ + import scala.reflect.runtime.universe._ case class Point(x: Int, y: Int) object Point { From 5e5b22979ca2a1c431588c79f6cc73267858b655 Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Thu, 30 May 2019 17:14:15 +0800 Subject: [PATCH 0489/3075] Fix Chinese Simple(zh_CN) version of issue#1339, which is refining pattern matching. --- _zh-cn/tour/pattern-matching.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_zh-cn/tour/pattern-matching.md b/_zh-cn/tour/pattern-matching.md index 8f03480ac6..c9727b304d 100644 --- a/_zh-cn/tour/pattern-matching.md +++ b/_zh-cn/tour/pattern-matching.md @@ -28,19 +28,19 @@ x match { case 0 => "zero" case 1 => "one" case 2 => "two" - case _ => "many" + case _ => "other" } ``` -上述代码中的`val x`是一个0到10之间的随机整数,将它放在`match`运算符的左侧对其进行模式匹配,`match`的右侧是包含4条`case`的表达式,其中最后一个`case _`表示匹配其余所有情况,在这里即是`x`大于2的情况。 +上述代码中的`val x`是一个0到10之间的随机整数,将它放在`match`运算符的左侧对其进行模式匹配,`match`的右侧是包含4条`case`的表达式,其中最后一个`case _`表示匹配其余所有情况,在这里就是其他可能的整型值。 `match`表达式具有一个结果值 ```tut def matchTest(x: Int): String = x match { case 1 => "one" case 2 => "two" - case _ => "many" + case _ => "other" } -matchTest(3) // many +matchTest(3) // other matchTest(1) // one ``` 这个`match`表达式是String类型的,因为所有的情况(case)均返回String,所以`matchTest`函数的返回值是String类型。 From 099fe2fcd30d42e296cf504ee5687582755f9bf0 Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Fri, 31 May 2019 12:46:00 +0800 Subject: [PATCH 0490/3075] Fix Chinese Simple(zh_CN) version of issue#1339, based on commit https://github.com/scala/docs.scala-lang/commit/ff6580c6247ee091b4805335a67480f2153c3bec. --- _zh-cn/tour/pattern-matching.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_zh-cn/tour/pattern-matching.md b/_zh-cn/tour/pattern-matching.md index c9727b304d..7ea9fec48e 100644 --- a/_zh-cn/tour/pattern-matching.md +++ b/_zh-cn/tour/pattern-matching.md @@ -66,8 +66,8 @@ case class VoiceRecording(contactName: String, link: String) extends Notificatio ``` def showNotification(notification: Notification): String = { notification match { - case Email(email, title, _) => - s"You got an email from $email with title: $title" + case Email(sender, title, _) => + s"You got an email from $sender with title: $title" case SMS(number, message) => s"You got an SMS from $number! Message: $message" case VoiceRecording(name, link) => @@ -81,7 +81,7 @@ println(showNotification(someSms)) // prints You got an SMS from 12345! Message println(showNotification(someVoiceRecording)) // you received a Voice Recording from Tom! Click the link to hear it: voicerecording.org/id/123 ``` -`showNotification`函数接受一个抽象类`Notification`对象作为输入参数,然后匹配其具体类型。(也就是判断它是一个`Email`,`SMS`,还是`VoiceRecording`)。在`case Email(email, title, _)`中,对象的`email`和`title`属性在返回值中被使用,而`body`属性则被忽略,故使用`_`代替。 +`showNotification`函数接受一个抽象类`Notification`对象作为输入参数,然后匹配其具体类型。(也就是判断它是一个`Email`,`SMS`,还是`VoiceRecording`)。在`case Email(sender, title, _)`中,对象的`sender`和`title`属性在返回值中被使用,而`body`属性则被忽略,故使用`_`代替。 ## 模式守卫(Pattern gaurds) 为了让匹配更加具体,可以使用模式守卫,也就是在模式后面加上`if `。 @@ -89,7 +89,7 @@ println(showNotification(someVoiceRecording)) // you received a Voice Recording def showImportantNotification(notification: Notification, importantPeopleInfo: Seq[String]): String = { notification match { - case Email(email, _, _) if importantPeopleInfo.contains(email) => + case Email(sender, _, _) if importantPeopleInfo.contains(sender) => "You got an email from special someone!" case SMS(number, _) if importantPeopleInfo.contains(number) => "You got an SMS from special someone!" @@ -111,7 +111,7 @@ println(showImportantNotification(importantEmail, importantPeopleInfo)) println(showImportantNotification(importantSms, importantPeopleInfo)) ``` -在`case Email(email, _, _) if importantPeopleInfo.contains(email)`中,除了要求`notification`是`Email`类型外,还需要`email`在重要人物列表`importantPeopleInfo`中,才会匹配到该模式。 +在`case Email(sender, _, _) if importantPeopleInfo.contains(sender)`中,除了要求`notification`是`Email`类型外,还需要`sender`在重要人物列表`importantPeopleInfo`中,才会匹配到该模式。 ## 仅匹配类型 From 1c7b5b6f9f7e7fea1b26206759215dd1a7491862 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Fri, 31 May 2019 22:01:55 +0200 Subject: [PATCH 0491/3075] hello Scala 2.13.0-RC3 --- api/all.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/api/all.md b/api/all.md index d2caf5f5a7..77ecd28618 100644 --- a/api/all.md +++ b/api/all.md @@ -28,10 +28,10 @@ includeTOC: true ## Prereleases -* Scala 2.13.0-RC2 - * [Library API](https://www.scala-lang.org/api/2.13.0-RC2/) - * [Compiler API](https://www.scala-lang.org/api/2.13.0-RC2/scala-compiler/scala/) - * [Reflection API](https://www.scala-lang.org/api/2.13.0-RC2/scala-reflect/scala/reflect/) +* Scala 2.13.0-RC3 + * [Library API](https://www.scala-lang.org/api/2.13.0-RC3/) + * [Compiler API](https://www.scala-lang.org/api/2.13.0-RC3/scala-compiler/scala/) + * [Reflection API](https://www.scala-lang.org/api/2.13.0-RC3/scala-reflect/scala/reflect/) ## Nightly builds From 0e3b437e0a73d31900a8c702ac28e6454cde63e2 Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Sun, 2 Jun 2019 11:16:32 +0800 Subject: [PATCH 0492/3075] Fix Chinese Simple(zh_CN) version of issue#1339, based on commit https://github.com/scala/docs.scala-lang/commit/55ed64e205d80298f59a6724bd7c44a26ec6e0e7 (Fix: should extend NotUniversal trait) --- _zh-cn/overviews/core/value-classes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_zh-cn/overviews/core/value-classes.md b/_zh-cn/overviews/core/value-classes.md index 85014abdb8..b731b9da0e 100644 --- a/_zh-cn/overviews/core/value-classes.md +++ b/_zh-cn/overviews/core/value-classes.md @@ -226,7 +226,7 @@ value class不能将惰性val或val作为成员,也不能有嵌套类、trait value类不能继承non-universal trait,并且其本身不能被继承: trait NotUniversal - class Value(val x: Int) extends AnyVal with notUniversal + class Value(val x: Int) extends AnyVal with NotUniversal class Extend(x: Int) extends Value(x) Extend.scala:2: error: illegal inheritance; superclass AnyVal From 749a5dce75eb7a794e5eb075b6b4c36b435f9dd6 Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Sun, 2 Jun 2019 12:05:38 +0800 Subject: [PATCH 0493/3075] Fix Chinese Simple(zh_CN) version of issue#1339, based on the latest commit of English originals. --- ...ions-between-java-and-scala-collections.md | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/_zh-cn/overviews/collections/conversions-between-java-and-scala-collections.md b/_zh-cn/overviews/collections/conversions-between-java-and-scala-collections.md index 9b8e44daf0..341dce3d87 100644 --- a/_zh-cn/overviews/collections/conversions-between-java-and-scala-collections.md +++ b/_zh-cn/overviews/collections/conversions-between-java-and-scala-collections.md @@ -16,14 +16,15 @@ language: zh-cn 某些时候,你需要将一种容器类型转换成另外一种类型。例如,你可能想要像访问Scala容器一样访问某个Java容器,或者你可能想将一个Scala容器像Java容器一样传递给某个Java方法。在Scala中,这是很容易的,因为Scala提供了大量的方法来隐式转换所有主要的Java和Scala容器类型。其中提供了如下的双向类型转换: - Iterator <=> java.util.Iterator - Iterator <=> java.util.Enumeration - Iterable <=> java.lang.Iterable - Iterable <=> java.util.Collection - mutable.Buffer <=> java.util.List - mutable.Set <=> java.util.Set - mutable.Map <=> java.util.Map - mutable.ConcurrentMap <=> java.util.concurrent.ConcurrentMap + + Iterator <=> java.util.Iterator + Iterator <=> java.util.Enumeration + Iterable <=> java.lang.Iterable + Iterable <=> java.util.Collection + mutable.Buffer <=> java.util.List + mutable.Set <=> java.util.Set + mutable.Map <=> java.util.Map + mutable.ConcurrentMap <=> java.util.concurrent.ConcurrentMap 使用这些转换很简单,只需从JavaConverters对象中import它们即可。 @@ -34,26 +35,30 @@ import之后,通过扩展方法 asScala 和 asJava 就可以在Scala容器和 scala> import collection.mutable._ import collection.mutable._ + scala> val jul: java.util.List[Int] = ArrayBuffer(1, 2, 3).asJava jul: java.util.List[Int] = [1, 2, 3] + scala> val buf: Seq[Int] = jul.asScala buf: scala.collection.mutable.Seq[Int] = ArrayBuffer(1, 2, 3) + scala> val m: java.util.Map[String, Int] = HashMap("abc" -> 1, "hello" -> 2).asJava - m: java.util.Map[String, Int] = {hello=2, abc=1} + m: java.util.Map[String,Int] = {abc=1, hello=2} 在Scala内部,这些转换是通过一系列“包装”对象完成的,这些对象会将相应的方法调用转发至底层的容器对象。所以容器不会在Java和Scala之间拷贝来拷贝去。一个值得注意的特性是,如果你将一个Java容器转换成其对应的Scala容器,然后再将其转换回同样的Java容器,最终得到的是一个和一开始完全相同的容器对象(译注:这里的相同意味着这两个对象实际上是指向同一片内存区域的引用,容器转换过程中没有任何的拷贝发生)。 还有一些Scala容器类型可以转换成对应的Java类型,但是并没有将相应的Java类型转换成Scala类型的能力,它们是: - Seq => java.util.List - mutable.Seq => java.util.List - Set => java.util.Set - Map => java.util.Map + Seq => java.util.List + mutable.Seq => java.util.List + Set => java.util.Set + Map => java.util.Map 因为Java并未区分可变容器不可变容器类型,所以,虽然能将`scala.immutable.List`转换成`java.util.List`,但所有的修改操作都会抛出“UnsupportedOperationException”。参见下例: - scala> jul = List(1, 2, 3).asJava + scala> val jul = List(1, 2, 3).asJava jul: java.util.List[Int] = [1, 2, 3] + scala> jul.add(7) java.lang.UnsupportedOperationException - at java.util.AbstractList.add(AbstractList.java:131) + at java.util.AbstractList.add(AbstractList.java:148) From 2893df074cdf8372a0591cde341fe58c2d1414c8 Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Sun, 2 Jun 2019 12:09:13 +0800 Subject: [PATCH 0494/3075] Typo in _overviews/collections/conversions-between-java-and-scala-collections.md . --- .../conversions-between-java-and-scala-collections.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/collections/conversions-between-java-and-scala-collections.md b/_overviews/collections/conversions-between-java-and-scala-collections.md index fb184cfac2..c476d4369c 100644 --- a/_overviews/collections/conversions-between-java-and-scala-collections.md +++ b/_overviews/collections/conversions-between-java-and-scala-collections.md @@ -46,7 +46,7 @@ This enables conversions between Scala collections and their corresponding Java scala> val m: java.util.Map[String, Int] = HashMap("abc" -> 1, "hello" -> 2).asJava m: java.util.Map[String,Int] = {abc=1, hello=2} -Internally, these conversion work by setting up a "wrapper" object that forwards all operations to the underlying collection object. So collections are never copied when converting between Java and Scala. An interesting property is that if you do a round-trip conversion from, say a Java type to its corresponding Scala type, and back to the same Java type, you end up with the identical collection object you have started with. +Internally, these conversions work by setting up a "wrapper" object that forwards all operations to the underlying collection object. So collections are never copied when converting between Java and Scala. An interesting property is that if you do a round-trip conversion from, say a Java type to its corresponding Scala type, and back to the same Java type, you end up with the identical collection object you have started with. Certain other Scala collections can also be converted to Java, but do not have a conversion back to the original Scala type: From 4f7da4a9fa605139d8dcefc69fd011e5dd9c25ab Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Mon, 3 Jun 2019 10:32:39 +0800 Subject: [PATCH 0495/3075] Fix the contents layout of _zh-cn/overviews/collections/seqs.md . --- _zh-cn/overviews/collections/seqs.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_zh-cn/overviews/collections/seqs.md b/_zh-cn/overviews/collections/seqs.md index c9640efd99..adee18c33f 100644 --- a/_zh-cn/overviews/collections/seqs.md +++ b/_zh-cn/overviews/collections/seqs.md @@ -27,7 +27,7 @@ language: zh-cn 如果一个序列是可变的,它提供了另一种更新序列中的元素的,但有副作用的update方法,Scala中常有这样的语法,如seq(idx) = elem。它只是seq.update(idx, elem)的简写,所以update 提供了方便的赋值语法。应注意update 和updated之间的差异。update 再原来基础上更改序列中的元素,并且仅适用于可变序列。而updated 适用于所有的序列,它总是返回一个新序列,而不会修改原序列。 -## Seq类的操作 +### Seq类的操作 | WHAT IT IS | WHAT IT DOES | |------------------ | -------------------| @@ -79,13 +79,13 @@ language: zh-cn 常用线性序列有 `scala.collection.immutable.List`和`scala.collection.immutable.Stream`。常用索引序列有 `scala.Array scala.collection.mutable.ArrayBuffer`。Vector 类提供一个在索引访问和线性访问之间有趣的折中。它同时具有高效的恒定时间的索引开销,和恒定时间的线性访问开销。正因为如此,对于混合访问模式,vector是一个很好的基础。后面将详细介绍vector。 -## 缓冲器 +### 缓冲器 Buffers是可变序列一个重要的种类。它们不仅允许更新现有的元素,而且允许元素的插入、移除和在buffer尾部高效地添加新元素。buffer 支持的主要新方法有:用于在尾部添加元素的 `+=` 和 `++=`;用于在前方添加元素的`+=: `和` ++=:` ;用于插入元素的 `insert`和`insertAll`;以及用于删除元素的` remove` 和 `-=`。如下表所示。 ListBuffer和ArrayBuffer是常用的buffer实现 。顾名思义,ListBuffer依赖列表(List),支持高效地将它的元素转换成列表。而ArrayBuffer依赖数组(Array),能快速地转换成数组。 -## Buffer类的操作 +#### Buffer类的操作 | WHAT IT IS | WHAT IT DOES | |--------------------- | -----------------------| From 1a3243214af43a3fe9a1c07b073b6a35b3b43941 Mon Sep 17 00:00:00 2001 From: Alexander Ronsse-Tucherov Date: Tue, 4 Jun 2019 17:40:55 -0700 Subject: [PATCH 0496/3075] Change "seemless" to "seamless" --- _overviews/tutorials/scala-for-java-programmers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/tutorials/scala-for-java-programmers.md b/_overviews/tutorials/scala-for-java-programmers.md index ada65a08f7..3ed8305c2a 100644 --- a/_overviews/tutorials/scala-for-java-programmers.md +++ b/_overviews/tutorials/scala-for-java-programmers.md @@ -99,7 +99,7 @@ French-speaking part of Switzerland use the same conventions.) Java's class libraries define powerful utility classes, such as `Date` and `DateFormat`. Since Scala interoperates -seemlessly with Java, there is no need to implement equivalent +seamlessly with Java, there is no need to implement equivalent classes in the Scala class library--we can simply import the classes of the corresponding Java packages: From 7b31ea8f5a8a44678761080566a557009b0d8c36 Mon Sep 17 00:00:00 2001 From: Changlin Li Date: Wed, 5 Jun 2019 21:05:27 -0400 Subject: [PATCH 0497/3075] Fix buggy Regex definition The original Regex definition doesn't fully match the `background-image` value. --- _tour/regular-expression-patterns.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_tour/regular-expression-patterns.md b/_tour/regular-expression-patterns.md index ec07f9f368..2e0670879e 100644 --- a/_tour/regular-expression-patterns.md +++ b/_tour/regular-expression-patterns.md @@ -35,7 +35,7 @@ You can also search for groups of regular expressions using parentheses. ```tut import scala.util.matching.Regex -val keyValPattern: Regex = "([0-9a-zA-Z-#() ]+): ([0-9a-zA-Z-#() ]+)".r +val keyValPattern: Regex = "([0-9a-zA-Z- ]+): ([0-9a-zA-Z-#()/. ]+)".r val input: String = """background-color: #A03300; @@ -53,7 +53,7 @@ for (patternMatch <- keyValPattern.findAllMatchIn(input)) Here we parse out the keys and values of a String. Each match has a group of sub-matches. Here is the output: ``` key: background-color value: #A03300 -key: background-image value: url(img +key: background-image value: url(img/header100.png) key: background-position value: top center key: background-repeat value: repeat-x key: background-size value: 2160px 108px From b3bd621d8e8ddda1b726aa8c473186dd996447ed Mon Sep 17 00:00:00 2001 From: cclaudiu81 Date: Fri, 7 Jun 2019 00:30:42 +0300 Subject: [PATCH 0498/3075] Update higher-order-functions.md enhanced doc on methods that take fns as args --- _tour/higher-order-functions.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_tour/higher-order-functions.md b/_tour/higher-order-functions.md index efc8d37db2..d6d1681894 100644 --- a/_tour/higher-order-functions.md +++ b/_tour/higher-order-functions.md @@ -60,6 +60,8 @@ case class WeeklyWeatherForecast(temperatures: Seq[Double]) { ``` Here the method `convertCtoF` is passed to `forecastInFahrenheit`. This is possible because the compiler coerces `convertCtoF` to the function `x => convertCtoF(x)` (note: `x` will be a generated name which is guaranteed to be unique within its scope). + +In a pure Object Oriented world a good practice is to avoid exposing methods that are parameterized with functions that might escape the internal state of the objects. Leaking internal state might break the invariants of the object itself. ## Functions that accept functions One reason to use higher-order functions is to reduce redundant code. Let's say you wanted some methods that could raise someone's salaries by various factors. Without creating a higher-order function, From 6fefeb9bb018ff59592638d0ce2c8967845c39ca Mon Sep 17 00:00:00 2001 From: Red Liu Date: Sat, 8 Jun 2019 11:03:27 +0800 Subject: [PATCH 0499/3075] Fix translations of class for zh-cn --- _zh-cn/tour/classes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_zh-cn/tour/classes.md b/_zh-cn/tour/classes.md index e916677681..4e7ee73bc9 100644 --- a/_zh-cn/tour/classes.md +++ b/_zh-cn/tour/classes.md @@ -19,7 +19,7 @@ prerequisite-knowledge: no-return-keyword, type-declaration-syntax, string-inter Scala中的类是用于创建对象的蓝图,其中包含了方法、常量、变量、类型、对象、特质、类,这些统称为成员。类型、对象和特质将在后面的文章中介绍。 ## 类定义 -一个最简的类的定义就是关键字`class`+标识符,类名必须是大写。 +一个最简的类的定义就是关键字`class`+标识符,类名首字母应大写。 ```tut class User @@ -69,7 +69,7 @@ println(point2.y) // prints 2 这样的做法在实践中有利于使得表达明确无误。 ## 私有成员和Getter/Setter语法 -成员默认是公有(`public`)的。使用`private`访问修饰符可以在函数外部隐藏它们。 +成员默认是公有(`public`)的。使用`private`访问修饰符可以在类外部隐藏它们。 ```tut class Point { private var _x = 0 From d7d2d9b5d3893e50c87c14565dec66f8fb7e8a51 Mon Sep 17 00:00:00 2001 From: "Aaron S. Hawley" Date: Sun, 9 Jun 2019 11:19:51 -0400 Subject: [PATCH 0500/3075] Remove feedback section from Scalameta post Gitter link is a 404 not found --- _sips/sips/2016-09-09-inline-meta.md | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/_sips/sips/2016-09-09-inline-meta.md b/_sips/sips/2016-09-09-inline-meta.md index 803d6dfc05..3aae1b3fed 100644 --- a/_sips/sips/2016-09-09-inline-meta.md +++ b/_sips/sips/2016-09-09-inline-meta.md @@ -26,9 +26,6 @@ We did our best to extensively evaluate the design space and comprehensively doc As a result, this is going to be a very long read. If you're just interested in getting a quick idea of the proposal, you can read just the ["Intuition"][Intuition] section. -If you have any questions, feedback or ideas regarding this document, use the link provided -in the ["Feedback"][FeedbackSection] section to join the public discussion. - ## Motivation Def macros and macro annotations have become an integral @@ -71,7 +68,6 @@ and coming up with a lightweight declaration syntax. In this document, we presen * [Out of scope](#out-of-scope) * [Conclusion](#conclusion) * [Credits](#credits) - * [Feedback](#feedback) ## Intuition @@ -983,12 +979,6 @@ Tamer Mohammed Abdul-Radi, David Dudson, Takeshi D. Itoh, Oleksandr Olgashko and The prototype of IntelliJ integration was developed by Mikhail Mutcianko. -## Feedback - -In order to centralize the discussion, post your feedback and ideas to [http://gitter.im/scalameta/sips][FeedbackWebsite]. -Once we submit this document as a full-fledged SIP, we will update this section to include the official discussion forum -mandated by the SIP process. - ## References 1. [Prototype of scalac integration][PrototypeScalac] @@ -1019,8 +1009,6 @@ mandated by the SIP process. [AnonymousTypeProviders]: http://docs.scala-lang.org/overviews/macros/typeproviders.html#anonymous-type-providers [ExtractorMacros]: https://docs.scala-lang.org/overviews/macros/extractors.html [AnnotationsTypecheck]: https://github.com/scalamacros/paradise/issues/75 -[FeedbackSection]: #feedback -[FeedbackWebsite]: http://gitter.im/scalameta/sips [AppendixInteraction]: https://gist.github.com/xeno-by/e26a904051a171e4bc8b9096630220a7 [AppendixExpansion]: https://gist.github.com/xeno-by/5dde62aedcc23afc85ecf4d795ac67c2 [AppendixMeta]: https://gist.github.com/xeno-by/9741ce7532cb30368b3753521bbfce4e From dbab980783ce676f59f616ad815e237ec417d12e Mon Sep 17 00:00:00 2001 From: "Aaron S. Hawley" Date: Fri, 7 Jun 2019 08:50:51 -0400 Subject: [PATCH 0501/3075] Add generating Scaladoc --- _overviews/scaladoc/generate.md | 55 +++++++++++++++++++++++++++++++++ _overviews/scaladoc/overview.md | 5 +-- 2 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 _overviews/scaladoc/generate.md diff --git a/_overviews/scaladoc/generate.md b/_overviews/scaladoc/generate.md new file mode 100644 index 0000000000..a57e4cb0cb --- /dev/null +++ b/_overviews/scaladoc/generate.md @@ -0,0 +1,55 @@ +--- +layout: multipage-overview +title: Generating Scaladoc + +discourse: true + +partof: scaladoc +overview-name: Scaladoc + +num: 4 + +permalink: /overviews/scaladoc/:title.html +--- + +There are two ways to generate API documentation in HTML from your Scala code. Those options are: + +* use sbt to do it, +* use the scaladoc command-line tool. + +## Using sbt + +The easiest and most commonly used way to generate API documentation from your Scala code is with the build tool [sbt](https://www.scala-sbt.org). + +From the sbt console, run Scaladoc by simply running the `doc` task: + + > doc + [info] Main Scala API documentation to target/scala-2.12/api... + [info] model contains 1 documentable templates + [info] Main Scala API documentation successful. + [success] Total time: 20 s + +The HTML documentation will show up in the respective `target/` directory (or directories for builds with multiple projects) that sbt prints to the console output. + +For more information on using sbt on your system, see the [download instructions](https://www.scala-lang.org/download/) for [getting started with Scala and sbt on the command line]({{site.baseurl}}/getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.html). + +For additional information about configuring Scaladoc in sbt, see the [Generate API documentation](https://www.scala-sbt.org/1.x/docs/Howto-Scaladoc.html) section of the sbt reference manual. + +## Using scaladoc command + +If you use Scala commands directly to start a console with `scala` or compile with `scalac`, then you should have a `scaladoc` command-line utility, as well. This is a more advanced and less commonly used method of generating Scaladoc. + + $ scaladoc src/main/scala/App.scala + model contains 1 documentable templates + +This will put the HTML in the current directory. This is probably not what you want. It's preferable to output to a subdirectory. To specify a different target directory, use the `-d` commmand-line option: + + $ scaladoc -d build/ src/main/scala/App.scala + +For more information on the `scaladoc` command and what other command-line options it supports, see the [scaladoc man page](https://www.scala-lang.org/files/archive/nightly/docs/manual/html/scaladoc.html). + +This command is harder to operate with more complex projects containing both multiple Scala source files and library dependencies. This is why using sbt (see above) is easier and better suited for generating Scaladoc. + +The Scaladoc command exists because it precedied the development of sbt, but also because it is useful to the Scala development team with studying bug reports for Scaladoc. + +More information on directly using the Scala commands, like `scaladoc`, is discussed at [your first lines of Scala](https://www.scala-lang.org/documentation/your-first-lines-of-scala.html). diff --git a/_overviews/scaladoc/overview.md b/_overviews/scaladoc/overview.md index efe893b729..b31aea8ef5 100644 --- a/_overviews/scaladoc/overview.md +++ b/_overviews/scaladoc/overview.md @@ -17,10 +17,11 @@ system that lives in the comments of Scala source code and which generates documentation related to the code structure within which it is written. It is based on other comment based documentation systems like Javadoc. -There are two flavors of Scaladoc documentation: +There are three aspects of Scaladoc documentation: - **[Using the Scaladoc interface]({{ site.baseurl }}/overviews/scaladoc/interface.html)** – how to navigate and use generated Scaladoc documentation to learn more about a library. - - **[Generating documentation for your library with Scaladoc]({{ site.baseurl }}/overviews/scaladoc/for-library-authors.html)** – how to use Scaladoc to generate documentation for your library. + - **[Scaladoc for Library Authors]({{ site.baseurl }}/overviews/scaladoc/for-library-authors.html)** – how to add Scaladoc comments to generate documentation for your library. + - **[Generating documentation for your library with Scaladoc]({{ site.baseurl }}/overviews/scaladoc/generate.html)** – how to use Scaladoc to generate documentation for your library. ### Contributing to Scaladoc From 7b46f87893a3267a6eac82fec10ae38526996ea6 Mon Sep 17 00:00:00 2001 From: "Aaron S. Hawley" Date: Sun, 9 Jun 2019 08:55:24 -0400 Subject: [PATCH 0502/3075] Fix typos and spellings on Scaladoc page --- _overviews/scaladoc/generate.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_overviews/scaladoc/generate.md b/_overviews/scaladoc/generate.md index a57e4cb0cb..d50b19c5b7 100644 --- a/_overviews/scaladoc/generate.md +++ b/_overviews/scaladoc/generate.md @@ -42,7 +42,7 @@ If you use Scala commands directly to start a console with `scala` or compile wi $ scaladoc src/main/scala/App.scala model contains 1 documentable templates -This will put the HTML in the current directory. This is probably not what you want. It's preferable to output to a subdirectory. To specify a different target directory, use the `-d` commmand-line option: +This will put the HTML in the current directory. This is probably not what you want. It's preferable to output to a subdirectory. To specify a different target directory, use the `-d` command-line option: $ scaladoc -d build/ src/main/scala/App.scala @@ -50,6 +50,6 @@ For more information on the `scaladoc` command and what other command-line optio This command is harder to operate with more complex projects containing both multiple Scala source files and library dependencies. This is why using sbt (see above) is easier and better suited for generating Scaladoc. -The Scaladoc command exists because it precedied the development of sbt, but also because it is useful to the Scala development team with studying bug reports for Scaladoc. +The Scaladoc command exists because it preceded the development of sbt, but also because it is useful to the Scala development team with studying bug reports for Scaladoc. More information on directly using the Scala commands, like `scaladoc`, is discussed at [your first lines of Scala](https://www.scala-lang.org/documentation/your-first-lines-of-scala.html). From af88f6563bbe4db334c8c7077bfca0146a8c5b14 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Sun, 9 Jun 2019 08:59:36 -0400 Subject: [PATCH 0503/3075] Avoid confusion about sbt on Scaladoc page --- _overviews/scaladoc/generate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scaladoc/generate.md b/_overviews/scaladoc/generate.md index d50b19c5b7..4c26f39a08 100644 --- a/_overviews/scaladoc/generate.md +++ b/_overviews/scaladoc/generate.md @@ -21,7 +21,7 @@ There are two ways to generate API documentation in HTML from your Scala code. The easiest and most commonly used way to generate API documentation from your Scala code is with the build tool [sbt](https://www.scala-sbt.org). -From the sbt console, run Scaladoc by simply running the `doc` task: +In the sbt shell, generate Scaladoc by running `doc`: > doc [info] Main Scala API documentation to target/scala-2.12/api... From dbbd5f0db67db746d0356b3d8caec835d7cc6fe7 Mon Sep 17 00:00:00 2001 From: Akhtyam Sakaev Date: Mon, 10 Jun 2019 03:36:03 +0300 Subject: [PATCH 0504/3075] Fix typo --- _includes/footer.html | 2 +- _overviews/FAQ/collections.md | 6 +++--- _overviews/FAQ/context-bounds.md | 2 +- _overviews/FAQ/finding-implicits.md | 2 +- _overviews/FAQ/finding-symbols.md | 2 +- .../collections/migrating-from-scala-27.md | 2 +- .../core/architecture-of-scala-collections.md | 4 ++-- .../binary-compatibility-of-scala-releases.md | 4 ++-- _overviews/core/collections-migration-213.md | 2 +- _overviews/core/futures.md | 6 +++--- _overviews/core/implicit-classes.md | 4 ++-- _overviews/macros/blackbox-whitebox.md | 2 +- _overviews/macros/changelog211.md | 4 ++-- .../parallel-collections/architecture.md | 6 +++--- _overviews/quasiquotes/definition-details.md | 8 +++---- _overviews/quasiquotes/expression-details.md | 2 +- _overviews/quasiquotes/intro.md | 4 ++-- _overviews/quasiquotes/terminology.md | 2 +- _overviews/quasiquotes/type-details.md | 4 ++-- ...inary-compatibility-for-library-authors.md | 10 ++++----- .../2016-09-20-sip-20th-september-minutes.md | 4 ++-- _sips/minutes/2016-11-29-sip-minutes.md | 2 +- _sips/minutes/2017-02-14-sip-minutes.md | 4 ++-- _sips/minutes/2017-05-08-sip-minutes.md | 4 ++-- _sips/minutes/2018-05-18-sip-minutes.md | 6 +++--- _sips/minutes/2018-08-30-sip-minutes.md | 6 +++--- _sips/sip-tutorial.md | 4 ++-- .../2010-01-22-named-and-default-arguments.md | 20 +++++++++--------- _sips/sips/2010-01-22-scala-2-8-arrays.md | 10 ++++----- _sips/sips/2011-10-13-uncluttering-control.md | 2 +- _sips/sips/2012-01-21-futures-promises.md | 8 +++---- ...-05-31-improved-lazy-val-initialization.md | 6 +++--- _sips/sips/2014-06-27-42.type.md | 4 ++-- _sips/sips/2016-01-11-static-members.md | 6 +++--- ...07-priority-based-infix-type-precedence.md | 2 +- _sips/sips/2017-09-20-opaque-types.md | 4 ++-- .../2018-07-31-interpolation-quote-escape.md | 8 +++---- _tour/automatic-closures.md | 2 +- _tour/traits.md | 2 +- contribute.md | 2 +- ...g-a-scala-project-with-intellij-and-sbt.md | 12 +++++------ ...ting-scala-with-sbt-on-the-command-line.md | 6 +++--- ...les-in-scala-impressions-and-statistics.md | 2 +- ...png => forward_backward_compatibility.png} | Bin 44 files changed, 102 insertions(+), 102 deletions(-) rename resources/images/library-author-guide/{fowards_backwards_compatibility.png => forward_backward_compatibility.png} (100%) diff --git a/_includes/footer.html b/_includes/footer.html index 6d233e5c8e..eb43f821b8 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -53,7 +53,7 @@ - + {% if page.layout == "sips"%} diff --git a/_overviews/FAQ/collections.md b/_overviews/FAQ/collections.md index b044191727..d78a2340a9 100644 --- a/_overviews/FAQ/collections.md +++ b/_overviews/FAQ/collections.md @@ -167,7 +167,7 @@ The operation is meant to traverse all elements of the collection, and apply the given operation f to each element. The application is done for its side effect only; in fact any function result of f is discarded by foreach. -Traversible objects can be finite or infinite. An example of an infinite +Traversable objects can be finite or infinite. An example of an infinite traversable object is the stream of natural numbers `Stream.from(0)`. The method `hasDefiniteSize` indicates whether a collection is possibly infinite. If `hasDefiniteSize` returns true, the collection is certainly finite. If it @@ -250,7 +250,7 @@ it. Also available are some traits with further refinements, such as * `LinearSeq` -- A trait for linear sequences, with efficient time for `isEmpty`, `head` and `tail`. * `immutable.LinearSeq` - * `immutable.List` -- An immutable, singlely-linked, list implementation. + * `immutable.List` -- An immutable, singly-linked, list implementation. * `immutable.Stream` -- A lazy-list. Its elements are only computed on-demand, but memoized (kept in memory) afterwards. It can be theoretically infinite. * `mutable.LinearSeq` * `mutable.DoublyLinkedList` -- A list with mutable `prev`, `head` (`elem`) and `tail` (`next`). @@ -343,7 +343,7 @@ it. Also available are some traits with further refinements, such as This was done to achieve maximum code reuse. The concrete *generic* implementation for classes with a certain structure (a traversable, a map, etc) is done in the Like classes. The classes intended for general consumption, -then, override selected methods that can be optmized. +then, override selected methods that can be optimized. * What the companion methods are for (e.g. List.companion)? diff --git a/_overviews/FAQ/context-bounds.md b/_overviews/FAQ/context-bounds.md index fa0beaaaa6..ad79c2990d 100644 --- a/_overviews/FAQ/context-bounds.md +++ b/_overviews/FAQ/context-bounds.md @@ -40,7 +40,7 @@ Another very common example in the library is a bit more complex: def f[A : Ordering](a: A, b: A) = implicitly[Ordering[A]].compare(a, b) -Here, `implicitly` is used to retrive the implicit value we want, one of type +Here, `implicitly` is used to retrieve the implicit value we want, one of type `Ordering[A]`, which class defines the method `compare(a: A, b: A): Int`. We'll see another way of doing this below. diff --git a/_overviews/FAQ/finding-implicits.md b/_overviews/FAQ/finding-implicits.md index 015216f28c..69a1c4a49e 100644 --- a/_overviews/FAQ/finding-implicits.md +++ b/_overviews/FAQ/finding-implicits.md @@ -219,7 +219,7 @@ by a `t` that is not implicit, so no implicit `T` is in scope. The invocation of `f` was enabled by importing from `Y.X.`. But it is not convenient to require an import to access implicit values -providied by a package. +provided by a package. If an implicit value is not found in lexical scope, implicit search continues in implicit scope. diff --git a/_overviews/FAQ/finding-symbols.md b/_overviews/FAQ/finding-symbols.md index 0512856737..aca08ae12f 100644 --- a/_overviews/FAQ/finding-symbols.md +++ b/_overviews/FAQ/finding-symbols.md @@ -160,7 +160,7 @@ object of type that is receiving the method. For example, consider `"a" -> 1`. W to look for an implicit which works on `"a"`, and so it can take `String`, one of its supertypes (`AnyRef` or `Any`) or a type parameter. In this case, we find `implicit final class ArrowAssoc[A](private val self: A)` which makes this implicit -avaialable on all types. +available on all types. Other implicit conversions may be visible in your scope depending on imports, extended types or self-type annotations. See [Finding implicits](finding-implicits.html) for details. diff --git a/_overviews/collections/migrating-from-scala-27.md b/_overviews/collections/migrating-from-scala-27.md index c2c2bd9935..87f557ca4f 100644 --- a/_overviews/collections/migrating-from-scala-27.md +++ b/_overviews/collections/migrating-from-scala-27.md @@ -41,7 +41,7 @@ Generally, the old functionality of Scala 2.7 collections has been left in place There are two parts of the old libraries which have been replaced wholesale, and for which deprecation warnings were not feasible. -1. The previous `scala.collection.jcl` package is gone. This package tried to mimick some of the Java collection library design in Scala, but in doing so broke many symmetries. Most people who wanted Java collections bypassed `jcl` and used `java.util` directly. Scala 2.8 offers automatic conversion mechanisms between both collection libraries in the [JavaConversions]({{ site.baseurl }}/overviews/collections/conversions-between-java-and-scala-collections.html) object which replaces the `jcl` package. +1. The previous `scala.collection.jcl` package is gone. This package tried to mimic some of the Java collection library design in Scala, but in doing so broke many symmetries. Most people who wanted Java collections bypassed `jcl` and used `java.util` directly. Scala 2.8 offers automatic conversion mechanisms between both collection libraries in the [JavaConversions]({{ site.baseurl }}/overviews/collections/conversions-between-java-and-scala-collections.html) object which replaces the `jcl` package. 2. Projections have been generalized and cleaned up and are now available as views. It seems that projections were used rarely, so not much code should be affected by this change. So, if your code uses either `jcl` or projections there might be some minor rewriting to do. diff --git a/_overviews/core/architecture-of-scala-collections.md b/_overviews/core/architecture-of-scala-collections.md index 5cb894f1e9..3a2dcf6fb4 100644 --- a/_overviews/core/architecture-of-scala-collections.md +++ b/_overviews/core/architecture-of-scala-collections.md @@ -907,7 +907,7 @@ return with `None`. The combined selection over an option value `opt` is elegantly expressed using `opt.flatMap(x => f(x))`. When applied to an optional value that is `None`, it returns `None`. Otherwise `opt` is `Some(x)` and the function `f` is applied to the encapsulated value `x`, -yielding a new option, which is returned by the flatmap. +yielding a new option, which is returned by the flatMap. The next two methods to implement for a mutable map are `+=` and `-=`. In the implementation of `PrefixMap`, these are defined in terms of two @@ -948,7 +948,7 @@ using the map's `+=` method. For immutable maps, the non-destructive element addition method `+` is used instead of method `+=`. Sets work in the same way. -However, in all these cases, to build the right kind of colletion +However, in all these cases, to build the right kind of collection you need to start with an empty collection of that kind. This is provided by the `empty` method, which is the last method defined in `PrefixMap`. This method simply returns a fresh `PrefixMap`. diff --git a/_overviews/core/binary-compatibility-of-scala-releases.md b/_overviews/core/binary-compatibility-of-scala-releases.md index c12db85230..749a31f6cc 100644 --- a/_overviews/core/binary-compatibility-of-scala-releases.md +++ b/_overviews/core/binary-compatibility-of-scala-releases.md @@ -11,8 +11,8 @@ When two versions of Scala are binary compatible, it is safe to compile your pro We check binary compatibility automatically with [MiMa](https://github.com/lightbend/migration-manager). We strive to maintain a similar invariant for the `behavior` (as opposed to just linkage) of the standard library, but this is not checked mechanically (Scala is not a proof assistant so this is out of reach for its type system). -#### Forwards and Back -We distinguish forwards and backwards compatibility (think of these as properties of a sequence of versions, not of an individual version). Maintaining backwards compatibility means code compiled on an older version will link with code compiled with newer ones. Forwards compatibility allows you to compile on new versions and run on older ones. +#### Forward and Back +We distinguish forward and backward compatibility (think of these as properties of a sequence of versions, not of an individual version). Maintaining backwards compatibility means code compiled on an older version will link with code compiled with newer ones. Forward compatibility allows you to compile on new versions and run on older ones. Thus, backwards compatibility precludes the removal of (non-private) methods, as older versions could call them, not knowing they would be removed, whereas forwards compatibility disallows adding new (non-private) methods, because newer programs may come to depend on them, which would prevent them from running on older versions (private methods are exempted here as well, as their definition and call sites must be in the same compilation unit). diff --git a/_overviews/core/collections-migration-213.md b/_overviews/core/collections-migration-213.md index 71b9cbf815..f2b33ae434 100644 --- a/_overviews/core/collections-migration-213.md +++ b/_overviews/core/collections-migration-213.md @@ -29,7 +29,7 @@ The most important changes in the Scala 2.13 collections library are: The [scala-collection-compat](https://github.com/scala/scala-collection-compat) is a library released for 2.11, 2.12 and 2.13 that provides some of the new APIs from Scala 2.13 for the older versions. This simplifies cross-building projects. -The module also provides [migratrion rules](https://github.com/scala/scala-collection-compat#migration-tool) for [scalafix](https://scalacenter.github.io/scalafix/docs/users/installation.html) that can update a project's source code to work with the 2.13 collections library. +The module also provides [migration rules](https://github.com/scala/scala-collection-compat#migration-tool) for [scalafix](https://scalacenter.github.io/scalafix/docs/users/installation.html) that can update a project's source code to work with the 2.13 collections library. ## scala.Seq, varargs and scala.IndexedSeq migration diff --git a/_overviews/core/futures.md b/_overviews/core/futures.md index c753fca53d..a0eea92daf 100644 --- a/_overviews/core/futures.md +++ b/_overviews/core/futures.md @@ -665,16 +665,16 @@ multiple `andThen` calls are ordered, as in the following example which stores the recent posts from a social network to a mutable set and then renders all the posts to the screen: - val allposts = mutable.Set[String]() + val allPosts = mutable.Set[String]() Future { session.getRecentPosts } andThen { - case Success(posts) => allposts ++= posts + case Success(posts) => allPosts ++= posts } andThen { case _ => clearAll() - for (post <- allposts) render(post) + for (post <- allPosts) render(post) } In summary, the combinators on futures are purely functional. diff --git a/_overviews/core/implicit-classes.md b/_overviews/core/implicit-classes.md index 9b3d819d87..501724cdb4 100644 --- a/_overviews/core/implicit-classes.md +++ b/_overviews/core/implicit-classes.md @@ -72,8 +72,8 @@ Implicit classes have the following restrictions: implicit class RichDate(date: java.util.Date) // OK! - implicit class Indexer[T](collecton: Seq[T], index: Int) // BAD! - implicit class Indexer[T](collecton: Seq[T])(implicit index: Index) // OK! + implicit class Indexer[T](collection: Seq[T], index: Int) // BAD! + implicit class Indexer[T](collection: Seq[T])(implicit index: Index) // OK! While it's possible to create an implicit class with more than one non-implicit argument, such classes diff --git a/_overviews/macros/blackbox-whitebox.md b/_overviews/macros/blackbox-whitebox.md index aade9367f2..f243e4ac74 100644 --- a/_overviews/macros/blackbox-whitebox.md +++ b/_overviews/macros/blackbox-whitebox.md @@ -29,7 +29,7 @@ In fact, macros became an important part of our ecosystem so quickly that just a Macro flavors are plentiful, so we decided to carefully examine them to figure out which ones should be put in the standard. This entails answering a few important questions. Why are macros working so well? Why do people use them? Our hypothesis is that this happens because the hard to comprehend notion of metaprogramming expressed in def macros piggybacks on the familiar concept of a typed method call. Thanks to that, the code that users write can absorb more meaning without becoming bloated or losing -compehensibility. +comprehensibility. ## Blackbox and whitebox macros diff --git a/_overviews/macros/changelog211.md b/_overviews/macros/changelog211.md index 0b91acfb4c..c4753e56ea 100644 --- a/_overviews/macros/changelog211.md +++ b/_overviews/macros/changelog211.md @@ -60,7 +60,7 @@ Quasiquotes is the single most impressive upgrade for reflection and macros in S 16) **[knownDirectSubclasses is deemed to be officially broken](https://issues.scala-lang.org/browse/SI-7046)**. A lot of users who tried to traverse sealed hierarchies of classes have noticed that `ClassSymbol.knownDirectSubclasses` only works if invocations of their macros come after the definitions of those hierarchies in Scala's compilation order. For instance, if a sealed hierarchy is defined in the bottom of a source file, and a macro application is written in the top of the file, then knownDirectSubclasses will return an empty list. This is an issue that is deeply rooted in Scala's internal architecture, and we can't provide a fix for it in the near future. -17) **showCode**. Along with `Tree.toString` that prints Scala-ish source code and `showRaw(tree)` that prints internal structures of trees, we now have `showCode` that prints compileable Scala source code corresponding to the provided tree, courtesy of Vladimir Nikolaev, who's done an amazing work of bringing this to life. We plan to eventually replace `Tree.toString` with `showCode`, but in Scala 2.11.0 these are two different methods. +17) **showCode**. Along with `Tree.toString` that prints Scala-ish source code and `showRaw(tree)` that prints internal structures of trees, we now have `showCode` that prints compilable Scala source code corresponding to the provided tree, courtesy of Vladimir Nikolaev, who's done an amazing work of bringing this to life. We plan to eventually replace `Tree.toString` with `showCode`, but in Scala 2.11.0 these are two different methods. 18) **[It is now possible to typecheck in type and pattern modes](https://issues.scala-lang.org/browse/SI-6814)**. A very convenient `Context.typeCheck` and `ToolBox.typeCheck` functionality of Scala 2.10.x had a significant inconvenience - it only worked for expressions, and typechecking something as a type or as a pattern required building dummy expressions. Now `typeCheck` has the mode parameter that take case of that difficulty. @@ -170,7 +170,7 @@ Quasiquotes is the single most impressive upgrade for reflection and macros in S // provides a source compatibility stub // in Scala 2.10.x, it will make `import compat._` compile just fine, // even though `c.universe` doesn't have `compat` - // in Scala 2.11.0, it will be ignored, becase `import c.universe._` + // in Scala 2.11.0, it will be ignored, because `import c.universe._` // brings its own `compat` in scope and that one takes precedence private object HasCompat { val compat = ??? }; import HasCompat._ diff --git a/_overviews/parallel-collections/architecture.md b/_overviews/parallel-collections/architecture.md index d5173e915f..487c6deac9 100644 --- a/_overviews/parallel-collections/architecture.md +++ b/_overviews/parallel-collections/architecture.md @@ -37,7 +37,7 @@ terms of two core abstractions-- `Splitter`s and `Combiner`s. ### Splitters The job of a `Splitter`, as its name suggests, is to split a parallel -collection into a non-trival partition of its elements. The basic idea is to +collection into a non-trivial partition of its elements. The basic idea is to split the collection into smaller parts until they are small enough to be operated on sequentially. @@ -55,7 +55,7 @@ subsets of elements of the whole parallel collection. And similar to normal `Iterator`s, a `Splitter` is invalidated after its `split` method is invoked. In general, collections are partitioned using `Splitter`s into subsets of -roughly the same size. In cases where more arbitrarily-sized partions are +roughly the same size. In cases where more arbitrarily-sized partitions are required, in particular on parallel sequences, a `PreciseSplitter` is used, which inherits `Splitter` and additionally implements a precise split method, `psplit`. @@ -82,7 +82,7 @@ and the type of the resulting collection, respectively. _Note:_ Given two `Combiner`s, `c1` and `c2` where `c1 eq c2` is `true` (meaning they're the same `Combiner`), invoking `c1.combine(c2)` always does -nothing and simpy returns the receiving `Combiner`, `c1`. +nothing and simply returns the receiving `Combiner`, `c1`. ## Hierarchy diff --git a/_overviews/quasiquotes/definition-details.md b/_overviews/quasiquotes/definition-details.md index d859b6d136..7d3c38e3cc 100644 --- a/_overviews/quasiquotes/definition-details.md +++ b/_overviews/quasiquotes/definition-details.md @@ -216,7 +216,7 @@ Abstract type definitions have the following shape: low: universe.Tree = high: universe.Tree = List[T] -Whenever one of the bounds isn\'t available, it gets represented as an [empty tree](expression-details.html#empty). Here each of the type arguments is a type definition itself. +Whenever one of the bounds isn't available, it gets represented as an [empty tree](expression-details.html#empty). Here each of the type arguments is a type definition itself. Another form of type definition is a type alias: @@ -259,7 +259,7 @@ Alternatively you can also deconstruct arguments, separating implicit and non-im implparams: List[universe.ValDef] = List(implicit val y: Int = _) body: universe.Tree = x.$plus(y) -This way of handling parameters will still work if the method doesn\'t have any implicit parameters and `implparams` will get extracted as an empty list: +This way of handling parameters will still work if the method doesn't have any implicit parameters and `implparams` will get extracted as an empty list: scala> val q"def g(...$paramss)(implicit ..$implparams) = $rhs" = q"def g(x: Int)(y: Int) = x + y" @@ -344,7 +344,7 @@ Packages are a fundamental primitive to organize source code. You can express th } }) -Quasiquotes don\'t support the inline package definition syntax that is usually used in the header of the source file (but it's equivalent to the supported one in terms of ASTs). +Quasiquotes don't support the inline package definition syntax that is usually used in the header of the source file (but it's equivalent to the supported one in terms of ASTs). ## Package Object Definition @@ -352,7 +352,7 @@ Package objects are a cross between packages and object: q"package object $tname extends { ..$earlydefns } with ..$parents { $self => ..$stats }" -All of the handling properties are equivalent to those of objects apart from the fact that they don\'t have [modifiers](#modifiers). +All of the handling properties are equivalent to those of objects apart from the fact that they don't have [modifiers](#modifiers). Even though package and regular objects seem to be quite similar syntactically, they don't match one another: diff --git a/_overviews/quasiquotes/expression-details.md b/_overviews/quasiquotes/expression-details.md index 371b7508dc..19cbc5ee67 100644 --- a/_overviews/quasiquotes/expression-details.md +++ b/_overviews/quasiquotes/expression-details.md @@ -290,7 +290,7 @@ At the moment, tuples are only supported up to an arity of 22, but this is just scala> val `tuple 23 supported?` = definitions.TupleClass(23) != NoSymbol tuple 23 supported?: Boolean = false -Despited the fact that `Tuple1` class exists there is no built-in syntax for it. Single parens around expression do not change its meaning: +Despite the fact that `Tuple1` class exists there is no built-in syntax for it. Single parens around expression do not change its meaning: scala> val inparens = q"(a)" inparens: universe.Ident = a diff --git a/_overviews/quasiquotes/intro.md b/_overviews/quasiquotes/intro.md index fbebb00f77..274a0d936f 100644 --- a/_overviews/quasiquotes/intro.md +++ b/_overviews/quasiquotes/intro.md @@ -73,7 +73,7 @@ Each of these contexts is covered by a separate interpolator: tq | [types]({{ site.baseurl }}/overviews/quasiquotes/syntax-summary.html#types) pq | [patterns]({{ site.baseurl }}/overviews/quasiquotes/syntax-summary.html#patterns) -Syntactical similarity between different contexts doesn\'t imply similarity between underlying trees: +Syntactical similarity between different contexts doesn't imply similarity between underlying trees: scala> println(q"List[Int]" equalsStructure tq"List[Int]") false @@ -110,7 +110,7 @@ Unquote splicing is a way to unquote a variable number of elements: scala> val fab = q"f(..$ab)" fab: universe.Tree = f(a, b) -Dots before the unquotee annotate indicate a degree of flattenning and are called a *splicing rank*. `..$` expects the argument to be an `Iterable[Tree]` and `...$` expects an `Iterable[Iterable[Tree]]`. +Dots before the unquotee annotate indicate a degree of flattening and are called a *splicing rank*. `..$` expects the argument to be an `Iterable[Tree]` and `...$` expects an `Iterable[Iterable[Tree]]`. Splicing can easily be combined with regular unquotation: diff --git a/_overviews/quasiquotes/terminology.md b/_overviews/quasiquotes/terminology.md index d528551c4c..3b153a2274 100644 --- a/_overviews/quasiquotes/terminology.md +++ b/_overviews/quasiquotes/terminology.md @@ -19,6 +19,6 @@ permalink: /overviews/quasiquotes/:title.html * **Tree deconstruction** refers to usages of quasiquotes as patterns to structurally tear apart trees. * **Unquoting** is a way of either putting things in or extracting things out of quasiquotes. Can be performed with `$` syntax within a quasiquote. * **Unquote splicing** (or just splicing) is another form of unquoting that flattens contents of the unquotee into a tree. Can be performed with either `..$` or `...$` syntax. -* **Rank** is a degree of flattenning of unquotee: `rank($) == 0`, `rank(..$) == 1`, `rank(...$) == 2`. +* **Rank** is a degree of flattening of unquotee: `rank($) == 0`, `rank(..$) == 1`, `rank(...$) == 2`. * [**Lifting**](lifting.html) is a way to unquote non-tree values and transform them into trees with the help of the `Liftable` typeclass. * [**Unlifting**](unlifting.html) is a way to unquote non-tree values out of quasiquote patterns with the help of the `Unliftable` typeclass. diff --git a/_overviews/quasiquotes/type-details.md b/_overviews/quasiquotes/type-details.md index b9d6929f22..9258d5928e 100644 --- a/_overviews/quasiquotes/type-details.md +++ b/_overviews/quasiquotes/type-details.md @@ -92,7 +92,7 @@ Lastly and [similarly to expressions](expression-details.html#super-and-this) on ## Applied Type -Instantiations of parametized types can be expressed with the help of applied types (type-level equivalent of type application): +Instantiations of parameterized types can be expressed with the help of applied types (type-level equivalent of type application): scala> val applied = tq"Foo[A, B]" applied: universe.Tree = Foo[A, B] @@ -151,7 +151,7 @@ Existential types consist of a type tree and a list of definitions: tpt: universe.Tree = List[T] defns: List[universe.MemberDef] = List(type T) -Alternatively there is also an underscrore notation: +Alternatively there is also an underscore notation: scala> val tq"$tpt forSome { ..$defns }" = tq"List[_]" tpt: universe.Tree = List[_$1] diff --git a/_overviews/tutorials/binary-compatibility-for-library-authors.md b/_overviews/tutorials/binary-compatibility-for-library-authors.md index d8cf3002da..655317c95d 100644 --- a/_overviews/tutorials/binary-compatibility-for-library-authors.md +++ b/_overviews/tutorials/binary-compatibility-for-library-authors.md @@ -79,23 +79,23 @@ Two library versions are **Binary Compatible** with each other if the compiled b ### Relationship between source and binary compatibility While breaking source compatibility often results in binary incompatibilities as well, they are actually orthogonal -- breaking one does not imply breaking the other. -#### Forwards and Backwards Compatibility +#### Forward and Backward Compatibility There are two "directions" when we describe compatibility of a library release: -**Backwards Compatible** means that a newer library version can be used in an environment where an older version is expected. When talking about binary and source compatibility, +**Backward Compatible** means that a newer library version can be used in an environment where an older version is expected. When talking about binary and source compatibility, this is the common and implied direction. -**Forwards Compatible** means that an older library can be used in an environment where a newer version is expected. +**Forward Compatible** means that an older library can be used in an environment where a newer version is expected. Forward compatibility is generally not upheld for libraries. Let's look at an example where library `A v1.0.0` is compiled with library `C v1.1.0`. -![Forwards and Backwards Compatibility]({{ site.baseurl }}/resources/images/library-author-guide/fowards_backwards_compatibility.png){: style="width: 65%; margin: auto; display: block"} +![Forward and Backward Compatibility]({{ site.baseurl }}/resources/images/library-author-guide/forward_backward_compatibility.png){: style="width: 65%; margin: auto; display: block"} `C v1.1.0 ` is **Forwards Binary Compatible** with `v1.0.0` if we can use `v1.0.0`'s JAR at runtime instead of `v1.1.0`'s JAR without any linkage errors. -`C v1.2.0 ` is **Backwards Binary Compatible** with `v1.1.0` if we can use `v1.2.0`'s JAR at runtime instead of `v1.1.0`'s JAR without any linkage errors. +`C v1.2.0 ` is **Backward Binary Compatible** with `v1.1.0` if we can use `v1.2.0`'s JAR at runtime instead of `v1.1.0`'s JAR without any linkage errors. ## Why binary compatibility matters diff --git a/_sips/minutes/2016-09-20-sip-20th-september-minutes.md b/_sips/minutes/2016-09-20-sip-20th-september-minutes.md index fe5bd46fe5..584975a64d 100644 --- a/_sips/minutes/2016-09-20-sip-20th-september-minutes.md +++ b/_sips/minutes/2016-09-20-sip-20th-september-minutes.md @@ -154,12 +154,12 @@ issue, two things are required: The second option is not feasible because unsigned numbers are AnyVals, and they can only extend `Object`. Working around this in the backend is, in Sébastien's opinion, not an exciting adventure to embark on: a lot of patches and quirky -fixes are required in the compiler. Sébastien, recognizing his unability to fix +fixes are required in the compiler. Sébastien, recognizing his inability to fix the issue, recommends to reject the proposal. Josh needs to leave. Eugene wonders if these problems are only JVM-specific. Sébastien replies that both yes and no, and he confirms that unsigned integers -will be implemented in Scalajs alone, so the implementation won't be +will be implemented in Scala.js alone, so the implementation won't be platform-independent. Eugene is interested in knowing if there will be any code duplication in the implementation, and Sébastien doesn't think so, since Scala Native implements unsigned integer in a different way. diff --git a/_sips/minutes/2016-11-29-sip-minutes.md b/_sips/minutes/2016-11-29-sip-minutes.md index a3736d79a0..c970ddb730 100644 --- a/_sips/minutes/2016-11-29-sip-minutes.md +++ b/_sips/minutes/2016-11-29-sip-minutes.md @@ -66,7 +66,7 @@ The main motivation is to prepare for inline. Inline won't work very well withou ### [SIP-NN:Static](https://github.com/scala/docs.scala-lang/pull/491/files) -Iulian says too much code is generated by annotations. We could solve name clashes the way ScalaJS does by specifying the exported name. How can we wake code generation predictable without looking at annotations? How do we emit public static field without accessors? Having everything emitted as static and object where possible is going to simplify reasoning about how things are initialized. +Iulian says too much code is generated by annotations. We could solve name clashes the way Scala.js does by specifying the exported name. How can we wake code generation predictable without looking at annotations? How do we emit public static field without accessors? Having everything emitted as static and object where possible is going to simplify reasoning about how things are initialized. How should a user decide when to use static? It is platform-dependent. diff --git a/_sips/minutes/2017-02-14-sip-minutes.md b/_sips/minutes/2017-02-14-sip-minutes.md index a1d8785ba0..ac54f216d3 100644 --- a/_sips/minutes/2017-02-14-sip-minutes.md +++ b/_sips/minutes/2017-02-14-sip-minutes.md @@ -147,7 +147,7 @@ The current SIP tries to make it behave as expected by the users in common cases **Jorge** We have to pass here both on this proposal as is right now but I think this could be dangerous in the case where we don't have an implementation for Scalac because maybe the details change and assume something in Scalac that the SIP is not able to predict or guard against it. Let's wait until next month and I will double check whether this is possible or not. Then I will get in touch with the Lightbend team to see whether this can be implemented or not. We'll decide in a month whether it should be accepted. -**Sébastien** ScalaJS already implemented it under another name but it's supposed to be conservative with respect to the aesthetic SIP in the sense that things that are allowed now with @jsstatic will also be allowed with @static. @static might open up a little bit more. +**Sébastien** Scala.js already implemented it under another name but it's supposed to be conservative with respect to the aesthetic SIP in the sense that things that are allowed now with @jsstatic will also be allowed with @static. @static might open up a little bit more. **Conclusion** The static SIP proposal has to be implemented in Scala, as it's already present in Dotty. Triplequote (Iulian Dragos and Mirco Dotta) has offered to provide an implementation targeting 2.12.3. @@ -221,7 +221,7 @@ There are multiple use cases covered by this SIP. I think the two most important **Martin** If you don't emit a Scala signature then you can't have a co- or contravariant type parameter because they are only expressed in Scala signatures, in Java it's not there. I don't see how that follows from the current proposal. Also, isn't it platform dependent? -**Sébastien** We do have a Java signature. Scala-JS doesn't disable classfile emission. When you say quickly compile, it uses the classfiles to quickly compile. when you use macros, it will extend from those classfiles. When you use an IDE it reduces the classfiles to identify things. When you use sbt, it uses classfiles to detect the changes. However, they aren't used by the ScalaJS linker. +**Sébastien** We do have a Java signature. Scala.js doesn't disable classfile emission. When you say quickly compile, it uses the classfiles to quickly compile. when you use macros, it will extend from those classfiles. When you use an IDE it reduces the classfiles to identify things. When you use sbt, it uses classfiles to detect the changes. However, they aren't used by the Scala.js linker. **Seth** Does this need to be part of the compiler or can it move forward as a plugin or just as a check performed in MiMa? MiMa just compares two different APIs. Can it have this other job as well: seeing if it does anything outside of the boundaries. diff --git a/_sips/minutes/2017-05-08-sip-minutes.md b/_sips/minutes/2017-05-08-sip-minutes.md index e5d2e52ccf..752873ef1b 100644 --- a/_sips/minutes/2017-05-08-sip-minutes.md +++ b/_sips/minutes/2017-05-08-sip-minutes.md @@ -47,12 +47,12 @@ Minutes were taken by Darja Jovanovic. Proposal aims to introduce new syntax from comprehension for monads to comonads. Martin is the reviewer. He asks others attendees for their opinion on this. Everyone had read the SIP. -**Eugene** referred to original proposal and wishes to see a better motivation for this language feature encouraging use of “plain English” to simplify the use of Scala as practice oriented language. He believes that it could be critical how this SIP can be improved. During the recent conference, organized by Facebook, he spoke with typescript guys that are developing idiomic solutions that would benefit typescript and javascript and allow community users to give their inputs. +**Eugene** referred to original proposal and wishes to see a better motivation for this language feature encouraging use of “plain English” to simplify the use of Scala as practice oriented language. He believes that it could be critical how this SIP can be improved. During the recent conference, organized by Facebook, he spoke with TypeScript guys that are developing idiomatic solutions that would benefit TypeScript and JavaScript and allow community users to give their inputs. Refers to the paper “Denotation” he linked in a proposal, that is not enough for Scala, but a good start. **Jorge** is getting back discussion on voting on this proposal and he mentioned that Josh insisted on more examples and suggestions on motivation of this SIP. -**Eugene** wanted to add more syntax (map and flatmap), but **Martin** opposed to that saying that Scala is quite serious program and needs more reason to add any additional syntax to it. **Martin** would like to see more widespread use of comonadic constructs and Libraries, and before doing that, he wouldn’t consider any further change. **Sebastian** agrees with Martin and says that he doesn’t really understand Josh’s and Eugene’s proposal. **Iulian** agrees that the proposal is quite complicated and he wonders how it can be useful. He believes that it is an interesting research direction, but that it needs more users feedbacks in aim to be included in the Scala, therefore questioning if the proposal should be numbered in the current form. Seth and Adriaan agree with Martin and Iulian. +**Eugene** wanted to add more syntax (map and flatMap), but **Martin** opposed to that saying that Scala is quite serious program and needs more reason to add any additional syntax to it. **Martin** would like to see more widespread use of comonadic constructs and Libraries, and before doing that, he wouldn’t consider any further change. **Sebastian** agrees with Martin and says that he doesn’t really understand Josh’s and Eugene’s proposal. **Iulian** agrees that the proposal is quite complicated and he wonders how it can be useful. He believes that it is an interesting research direction, but that it needs more users feedback in aim to be included in the Scala, therefore questioning if the proposal should be numbered in the current form. Seth and Adriaan agree with Martin and Iulian. **Conclusion** Proposal discarded unanimously. They will send the feedback to the author. diff --git a/_sips/minutes/2018-05-18-sip-minutes.md b/_sips/minutes/2018-05-18-sip-minutes.md index 3f4c390f78..b707f52f73 100644 --- a/_sips/minutes/2018-05-18-sip-minutes.md +++ b/_sips/minutes/2018-05-18-sip-minutes.md @@ -62,7 +62,7 @@ Given the short time and amount of decisions that need to be made, the Committee *Structure* a) Have a **list of changes**, grouped in batches that would be decided within the next year, meeting once a month -b) **Plan** - full and strucutured list of changes that need to be implemented consolidated between the Committee members using a shared a Google doc +b) **Plan** - full and structured list of changes that need to be implemented consolidated between the Committee members using a shared a Google doc c) **Public comments** - each batch should be published on the Contributors thread, for a month at a time in order to have community involved, share their opinion and contribute. Advise was proposed - each thread should clearly point out start and end date of collecting the comments/suggestions. *Organisation* @@ -80,10 +80,10 @@ The above mentioned structure and organisation was gathered throughout the meeti 4. Other: spec, quorum -**Heather** bings up an important question "What about Scala spec" ([YouTube time: 4'49''](https://youtu.be/q2LVmTe9qmU?t=289)) to which **Martin** responds within the next year we should know which features are included as a first priority but that spec should not be left for the last minute. +**Heather** brings up an important question "What about Scala spec" ([YouTube time: 4'49''](https://youtu.be/q2LVmTe9qmU?t=289)) to which **Martin** responds within the next year we should know which features are included as a first priority but that spec should not be left for the last minute. **Miles** ([YouTube time: 8'45](https://youtu.be/q2LVmTe9qmU?t=525))suggested that SIP proposals should include draft specification changes to save time and effort pulling the eventual spec update together. **Martin** ([YouTube time: 37'59''](https://youtu.be/q2LVmTe9qmU?t=2279)) also raised a question about the decision making process, asking if it would be better to change to simple majority when it comes to voting. This was rejected by most of the Members and agreed it should be discussed in a different meeting or time. -**Conclusion** The first batch should be agreed upon, posted on the Contributors thread for public comments. Such discussion should be summaraized and included in the next meeting (22nd June 2018, after ScalaDays NewYork). +**Conclusion** The first batch should be agreed upon, posted on the Contributors thread for public comments. Such discussion should be summarized and included in the next meeting (22nd June 2018, after ScalaDays NewYork). diff --git a/_sips/minutes/2018-08-30-sip-minutes.md b/_sips/minutes/2018-08-30-sip-minutes.md index 30fbc4bc49..48bc21c12f 100644 --- a/_sips/minutes/2018-08-30-sip-minutes.md +++ b/_sips/minutes/2018-08-30-sip-minutes.md @@ -141,7 +141,7 @@ Comments + Interaction with nullary constructors. Currently `class Foo` is interpreted as `class Foo()`. Mutatis mutandis for case class `apply` methods. -**Martin** ([Youtube time: 11.37](https://youtu.be/gnlL4PlstFY?t=688)) mentiones that this proposal also came about due to New collection usecases that surfaced in recent work - showing that without a strict rule there is a high amount of "un-disciplined" use of (). But he agrees with Miles about merging the two proposals together. +**Martin** ([Youtube time: 11.37](https://youtu.be/gnlL4PlstFY?t=688)) mentioned that this proposal also came about due to New collection usecases that surfaced in recent work - showing that without a strict rule there is a high amount of "un-disciplined" use of (). But he agrees with Miles about merging the two proposals together. **Conclusion** **Jorge** takes the task to merge the proposals and extend the motivation. @@ -210,7 +210,7 @@ Discussion: **Josh** ([YouTube time: 27’16’’](https://youtu.be/gnlL4PlstFY?t=1636)) clarifies that in order to replace the libraries one would need a proof of concept, and currently there is none. -**Adriaan** ([YouTube time 30’](https://youtu.be/gnlL4PlstFY?t=1796)) summarises the discussion, pointing out that Committee needs to answer a question *will we support XML in some way* and *waht would be the most "Scala-like" way to do so* and *who will be maintaing it*. +**Adriaan** ([YouTube time 30’](https://youtu.be/gnlL4PlstFY?t=1796)) summarises the discussion, pointing out that Committee needs to answer a question *will we support XML in some way* and *what would be the most "Scala-like" way to do so* and *who will be maintaining it*. **Seth** ([YouTube time 35’57’’](https://youtu.be/gnlL4PlstFY?t=2157)) is under the impression that large portion of XML user base are the ones using it to do generation and rarer to be reading in XML using the existing Scala XML support and asks others to share their impressions. **Martin** re-phrases it as “using XML for pattern matching”. @@ -269,7 +269,7 @@ Counter Proposals - Multiple "def" keywords, one which would mean side-effecting function := for side effects -**Josh** concludes: big point to debate would the language consistency be worth the change to more verbose expresion. +**Josh** concludes: big point to debate would the language consistency be worth the change to more verbose expression. **Iulian** ([You/tube time: ]( https://youtu.be/gnlL4PlstFY?t=2928)) adds that 1. last 5 years Syntax procedure was anyway deprecated; 2. going forward we should consider Scala 3 in a light of next 15 years, now is the right moment to clean up the language and 3. this is “the easiest refactoring to automate the code base” that could be a “zero cost migration” diff --git a/_sips/sip-tutorial.md b/_sips/sip-tutorial.md index 680eee2d73..b5ed7e03ae 100644 --- a/_sips/sip-tutorial.md +++ b/_sips/sip-tutorial.md @@ -11,7 +11,7 @@ The process to submit is simple: * Fork the [Scala documentation repository](http://github.com/scala/docs.scala-lang) and clone it. * Create a new SIP file in the `sips/pending/_posts/`. Use the [S(L)IP template](https://github.com/scala/docs.scala-lang/blob/master/_sips/sip-template.md) - * Make sure the new file follows the format: `YYYY-MM-dd-{title}.md`. Use the proposal date for `YYYY-MM-dd`. + * Make sure the new file follows the format: `YYYY-MM-dd-{title}.md`. Use the proposal date for `YYYY-MM-dd`. * Use the [Markdown Syntax](http://daringfireball.net/projects/markdown/syntax) to write your SIP. * Follow the instructions in the [README](https://github.com/scala/docs.scala-lang/blob/master/README.md) to build your SIP locally so you can ensure that it looks correct on the website. * Create a link to your SIP in the "pending sips" section of `index.md`. @@ -21,7 +21,7 @@ The process to submit is simple: ## SIP Post Format ## -First, create a new SIP file in the `pending/_posts` directory. Make sure the new file follows the format: `YYYY-MM-dd-{title}.md`. Where: +First, create a new SIP file in the `pending/_posts` directory. Make sure the new file follows the format: `YYYY-MM-dd-{title}.md`. Where: * `YYYY` is the current year when the proposal originated. * `MM` is the current month (`01` = January, `12` = December) when the proposal originated. * `dd` is the day of the month when the proposal originated. diff --git a/_sips/sips/2010-01-22-named-and-default-arguments.md b/_sips/sips/2010-01-22-named-and-default-arguments.md index fecaed1b71..a3d5a96165 100644 --- a/_sips/sips/2010-01-22-named-and-default-arguments.md +++ b/_sips/sips/2010-01-22-named-and-default-arguments.md @@ -16,13 +16,13 @@ The second language feature discussed in this document, default arguments, in ge ## Named Arguments -In Scala 2.8, method arguments can be specified in _named style_ using the same syntax as variable assignments: +In Scala 2.8, method arguments can be specified in _named style_ using the same syntax as variable assignments: def f[T](a: Int, b: T) f(b = getT(), a = getInt()) -The argument expressions are evaluated in call-site order, so in the above example `getT()` is executed before `getInt()`f. Mixing named and positional arguments is allowed as long as the positional part forms a prefix of the argument list: +The argument expressions are evaluated in call-site order, so in the above example `getT()` is executed before `getInt()`f. Mixing named and positional arguments is allowed as long as the positional part forms a prefix of the argument list: f(0, b = "1") // valid f(b = "1", a = 0) // valid @@ -51,7 +51,7 @@ The following list shows how named arguments interfere with other language featu **By-Name Parameters** continue to work as expected when using named arguments. The expression is only (and repeatedly) evaluated when the body of the method accesses the parameter. -**Repeated Parameters** When an application uses named arguments, the repeated parameter has to be specified exactly once. Using the same parameter name multiple times is disallowed. +**Repeated Parameters** When an application uses named arguments, the repeated parameter has to be specified exactly once. Using the same parameter name multiple times is disallowed. **Functional values** A functional value in Scala is an instance of a class which implements a method called apply. One can use the parameter names of that apply method for a named application. For functional values whose static type is scala.FunctionN, the parameter names of that apply method can be used. @@ -68,17 +68,17 @@ The following list shows how named arguments interfere with other language featu val a: A = new B a.f(a = 1) // OK -**Overloading Resolution** When a method application refers to an overloaded method, first the set of applicable alternatives is determined and then the most specific alternative is chosen (see [1], Chapter 6.26.3). +**Overloading Resolution** When a method application refers to an overloaded method, first the set of applicable alternatives is determined and then the most specific alternative is chosen (see [1], Chapter 6.26.3). -The presence of named argument influences the set of applicable alternatives, the argument types have to be matched against the corresponding parameter types based on the names. In the following example, the second alternative is applicable: +The presence of named argument influences the set of applicable alternatives, the argument types have to be matched against the corresponding parameter types based on the names. In the following example, the second alternative is applicable: def f() // #1 def f(a: Int, b: String) // #2 f(b = "someString", a = 1) // using #2 -If multiple alternatives are applicable, the most specific one is determined. This process is independent of the argument names used in a specific application and only looks at the method signature (for a detailed description, see [1], Chapter 6.26.3). +If multiple alternatives are applicable, the most specific one is determined. This process is independent of the argument names used in a specific application and only looks at the method signature (for a detailed description, see [1], Chapter 6.26.3). -In the following example, both alternatives are applicable, but none of them is more specific than the other because the argument types are compared based on their position, not on the argument name: +In the following example, both alternatives are applicable, but none of them is more specific than the other because the argument types are compared based on their position, not on the argument name: def f(a: Int, b: String) // #1 def f(b: Object, a: Int) // #2 @@ -113,7 +113,7 @@ A default argument may be an arbitrary expression. Since the scope of a paramete // def f(a: Int = 0, b: Int = a + 1) // "error: not found: value a" f(10)() // returns 11 (not 1) -A special expected type is used for type-checking the default argument `expr` of a method parameter `”x: T = expr”`: it is obtained by replacing all occurrences of type parameters of the method (type parameters of the class for constructors) with the undefined type. This allows specifying default arguments for polymorphic methods and classes: +A special expected type is used for type-checking the default argument `expr` of a method parameter `”x: T = expr”`: it is obtained by replacing all occurrences of type parameters of the method (type parameters of the class for constructors) with the undefined type. This allows specifying default arguments for polymorphic methods and classes: def f[T](a: T = 1) = a f() // returns 1: Int @@ -157,7 +157,7 @@ During type-checking, the static type is used to determine whether a parameter h def f(a: String, b: Int = 1) // #2 f("str") // both are applicable, #1 is selected -**Case Classes** For every case class, a method named `”copy”` is now generated which allows to easily create modified copies of the class’s instances. The copy method takes the same type and value parameters as the primary constructor of the case class, and every parameter defaults to the corresponding constructor parameter. +**Case Classes** For every case class, a method named `”copy”` is now generated which allows to easily create modified copies of the class’s instances. The copy method takes the same type and value parameters as the primary constructor of the case class, and every parameter defaults to the corresponding constructor parameter. case class A[T](a: T, b: Int) { // def copy[T’](a’: T’ = a, b’: Int = b): A[T’] = @@ -215,4 +215,4 @@ For constructor defaults, these methods are added to the companion object of the // } ## References -1. Odersky, M. _The Scala Language Specification, Version 2.11_. Available online at [http://www.scala-lang.org/files/archive/spec/2.11/](http://www.scala-lang.org/files/archive/spec/2.11/) +1. Odersky, M. _The Scala Language Specification, Version 2.11_. Available online at [http://www.scala-lang.org/files/archive/spec/2.11/](http://www.scala-lang.org/files/archive/spec/2.11/) diff --git a/_sips/sips/2010-01-22-scala-2-8-arrays.md b/_sips/sips/2010-01-22-scala-2-8-arrays.md index 407dc19bf1..3411fa929c 100644 --- a/_sips/sips/2010-01-22-scala-2-8-arrays.md +++ b/_sips/sips/2010-01-22-scala-2-8-arrays.md @@ -26,8 +26,8 @@ First, there’s actually not a single array type representation in Java but nine different ones: One representation for arrays of reference type and another eight for arrays of each of the primitive types `byte`, `char`, `short`, `int`, `long`, `float`, `double`, and `boolean`. There is no common -type for these different representations which is more specific than just -`java.lang.Object`, even though there are some reflective methods to deal with +type for these different representations which is more specific than just +`java.lang.Object`, even though there are some reflective methods to deal with arrays of arbitrary type in `java.lang.reflect.Array`. Second, there’s no way to create an array of a generic type; only monomorphic array creations are allowed. Third, the only operations supported by arrays are indexing, updates, @@ -35,14 +35,14 @@ and get length. Contrast this with what we would like to have in Scala: Arrays should slot into the collections hierarchy, supporting the hundred or so methods that are -defined on sequences. And they should certainly be generic, so that one can +defined on sequences. And they should certainly be generic, so that one can create an `Array[T]` where `T` is a type variable. ### The Past How to combine these desirables with the representation restrictions imposed by Java interoperability and performance? There’s no easy answer, and I -believe we got it wrong the first time when we designed Scala. The Scala +believe we got it wrong the first time when we designed Scala. The Scala language up to 2.7.x “magically” wrapped and unwrapped arrays when required in a process called boxing and unboxing, similarly to what is done to treat primitive numeric types as objects. “Magically” means: the compiler generated @@ -89,7 +89,7 @@ proposal is that one would not normally refer to Scala native arrays in user code, just as one rarely referred to RichString in Scala. One would only rely on the implicit conversion to add the necessary methods and traits to Java arrays. Unfortunately, the String/RichString experience has shown that this is -also problematic. In par- ticular, in pre 2.8 versions of Scala, one had the +also problematic. In particular, in pre 2.8 versions of Scala, one had the non-intuitive property that "abc".reverse.reverse == "abc" //, yet diff --git a/_sips/sips/2011-10-13-uncluttering-control.md b/_sips/sips/2011-10-13-uncluttering-control.md index 5f4dea8d64..e1ceb5d790 100644 --- a/_sips/sips/2011-10-13-uncluttering-control.md +++ b/_sips/sips/2011-10-13-uncluttering-control.md @@ -71,7 +71,7 @@ For while loops: To write a `do-while` inside a `while` loop you will need braces, like this: - while (expression1) { do expression2 while epression3 } + while (expression1) { do expression2 while expression3 } 3. In Scala 2.11: Disallow diff --git a/_sips/sips/2012-01-21-futures-promises.md b/_sips/sips/2012-01-21-futures-promises.md index a1b8d43666..11983d2201 100644 --- a/_sips/sips/2012-01-21-futures-promises.md +++ b/_sips/sips/2012-01-21-futures-promises.md @@ -109,7 +109,7 @@ We do so by calling the method `getRecentPosts` which returns a `List[String]`: f onComplete { case Right(posts) => for (post <- posts) render(post) - case Left(t) => render("An error has occured: " + t.getMessage) + case Left(t) => render("An error has occurred: " + t.getMessage) } The `onComplete` method is general in the sense that it allows the @@ -387,16 +387,16 @@ multiple `andThen` calls are ordered, as in the following example which stores the recent posts from a social network to a mutable set and then renders all the posts to the screen: - val allposts = mutable.Set[String]() + val allPosts = mutable.Set[String]() Future { session.getRecentPosts } andThen { - case Success(posts) => allposts ++= posts + case Success(posts) => allPosts ++= posts } andThen { case _ => clearAll() - for (post <- allposts) render(post) + for (post <- allPosts) render(post) } In summary, the combinators on futures are purely functional. diff --git a/_sips/sips/2013-05-31-improved-lazy-val-initialization.md b/_sips/sips/2013-05-31-improved-lazy-val-initialization.md index b3fc711ced..2ff2dfee7c 100644 --- a/_sips/sips/2013-05-31-improved-lazy-val-initialization.md +++ b/_sips/sips/2013-05-31-improved-lazy-val-initialization.md @@ -529,7 +529,7 @@ Note that this class is extracted from other place in standard library that uses - it requires usage of `identityHashCode` that is stored for every object inside object header. - as global arrays are used to store monitors, seemingly unrelated things may create contention. This is addressed in detail in evaluation section. -Both absence of monitor expansion and usage of `idetityHashCode` interact with +Both absence of monitor expansion and usage of `identityHashCode` interact with each other, as both of them operate on the object header. \[[12][12]\] presents the complete graph of transitions between possible states of the object header. What can be seen from this transition graph is that in the contended case, @@ -679,7 +679,7 @@ For those wishing to reproduce the results, the benchmarking suite takes 90 minu The final result of those benchmarks is that amount proposed versions, the two that worth considering are (V4-general) and (V6). They both perform better than the current implementation in all the contended case. -Specifically, in the contended case, V6 is 2 times fater than V1, while V4-general is 4 times faster. +Specifically, in the contended case, V6 is 2 times faster than V1, while V4-general is 4 times faster. Unfortunately V4-general is 30% slower in the uncontended case than current implementation(V1), while V6 is in the same ballpark, being up to 5% slower or faster depending on the setup of the benchmark. Based on this, we propose V6 to be used as default in future versions of Scala. @@ -699,7 +699,7 @@ Both Dotty and released Scala 2.12 already implement "Elegant Local lazy vals". ### Unsafe ### The proposed version, V6 relies on `sun.misc.Unsafe` in order to implement it's behaviour. -While `sun.misc.Unsafe` will remain availabe in Java9 there's an intention to deprecate it and replace it with VarHandles.\[[20][20]\]. +While `sun.misc.Unsafe` will remain available in Java9 there's an intention to deprecate it and replace it with VarHandles.\[[20][20]\]. The proposed version V6 can be implemented with using functionality present in Var Handles. ## Acknowledgements ## diff --git a/_sips/sips/2014-06-27-42.type.md b/_sips/sips/2014-06-27-42.type.md index 0c4e208810..afe0aeaeae 100644 --- a/_sips/sips/2014-06-27-42.type.md +++ b/_sips/sips/2014-06-27-42.type.md @@ -455,7 +455,7 @@ applications which work with large datasets. ``` This SIP updates the specification to match the current implementation and then adds the further - refinement that an explict upper bound of `Singleton` indicates that a singleton type should be + refinement that an explicit upper bound of `Singleton` indicates that a singleton type should be inferred. Given, @@ -592,7 +592,7 @@ the singleton types). This is desirable, but due to value class restrictions, en primitive types (such as `Int`). If we implemented `ValueOf[A]` as an opaque type instead of a value class, then this boxing -would be ellided, and the `valueOf[A]` method would be compiled to an identity function. +would be elided, and the `valueOf[A]` method would be compiled to an identity function. ## Related Scala issues resolved by the literal types implementation diff --git a/_sips/sips/2016-01-11-static-members.md b/_sips/sips/2016-01-11-static-members.md index 9fff070f02..3d98d6f5fe 100644 --- a/_sips/sips/2016-01-11-static-members.md +++ b/_sips/sips/2016-01-11-static-members.md @@ -97,7 +97,7 @@ object O { } {% endhighlight %} -Under the proposed scheme users will be able to opt-in to have the field `f` defined in the inner object `I` emited as a static field. +Under the proposed scheme users will be able to opt-in to have the field `f` defined in the inner object `I` emitted as a static field. In case `O.d` is annotated with `@static` the field will be created as a static field `d` in `class O`. If not annotated, it will be created in the companion module with a static forwarder `d` in `class O`. @@ -109,7 +109,7 @@ The following rules ensure that methods can be correctly compiled into static me 2. The fields annotated with `@static` should precede any non-`@static` fields. This ensures that we do not introduce surprises for users in initialization order of this class. -3. The right hand side of a method or field annotated with `@static` can only refer to top-level classes, members of globally accessible objects and `@static` members. In particular, for non-static objects `this` is not accesible. `super` is never accessible. +3. The right hand side of a method or field annotated with `@static` can only refer to top-level classes, members of globally accessible objects and `@static` members. In particular, for non-static objects `this` is not accessible. `super` is never accessible. 4. If a member `foo` of an `object C` is annotated with `@static`, the companion class `C` is not allowed to define term members with name `foo`. @@ -153,7 +153,7 @@ This means that no code precedes the `@static` field initialization which makes since fields are initialized in the order `as written`, similar to how normal fields are initialized. The `@static` proposal is similar to `@tailrec` in a sense that it fails compilation in the case where the user did not write code that follows the aforementioned rules. -These rules exist to enforce the unlikelyhood of an observable difference in semantics if `@static` annotations are dropped; +These rules exist to enforce the unlikelihood of an observable difference in semantics if `@static` annotations are dropped; The restrictions in this SIP make it hard to observe changes in initialization within the same object. It is still possible to observe those changes using multiple classes and side effects within initializers: diff --git a/_sips/sips/2017-02-07-priority-based-infix-type-precedence.md b/_sips/sips/2017-02-07-priority-based-infix-type-precedence.md index 95c73ab90d..8e2341c1eb 100644 --- a/_sips/sips/2017-02-07-priority-based-infix-type-precedence.md +++ b/_sips/sips/2017-02-07-priority-based-infix-type-precedence.md @@ -104,7 +104,7 @@ val fails : 1 + 2 * 3 + 4 = 11 //left associative:(((1+2)*3)+4))) = 13 ``` #### Developer issues example -[This](http://stackoverflow.com/questions/23333882/scala-infix-type-aliasing-for-2-type-parameters) stackoverflow question demonstrate developers are 'surprised' by the difference in infix precedence, expecting infix type precedence to act the same as expression operations. +[This](http://stackoverflow.com/questions/23333882/scala-infix-type-aliasing-for-2-type-parameters) Stack Overflow question demonstrate developers are 'surprised' by the difference in infix precedence, expecting infix type precedence to act the same as expression operations. --- diff --git a/_sips/sips/2017-09-20-opaque-types.md b/_sips/sips/2017-09-20-opaque-types.md index 7c8d5e3444..bbd4a798d3 100644 --- a/_sips/sips/2017-09-20-opaque-types.md +++ b/_sips/sips/2017-09-20-opaque-types.md @@ -885,7 +885,7 @@ there will certainly be an impact on the bytecode produced (and possibly the runtime performance). By contrast, replacing `String` with `Digits` is guaranteed to have no -impact (all occurances of `Digits` are guaranteed to be erased to +impact (all occurrences of `Digits` are guaranteed to be erased to `String`). Aside from the ergonomics of calling the `fromString` and `asString` methods, there's no runtime impact versus using the underlying type. @@ -953,7 +953,7 @@ but it is *not* a `List[AnyVal]`. Since value classes do have a runtime representation, they do increase the size of runtime artifacts produced (whether a JAR file, a -javascript file, or something else). Their methods are also compiled +JavaScript file, or something else). Their methods are also compiled to multiple representations (i.e. they support both the boxed and unboxed forms via extensions methods). Again, this comes at a cost. diff --git a/_sips/sips/2018-07-31-interpolation-quote-escape.md b/_sips/sips/2018-07-31-interpolation-quote-escape.md index bd5658d618..a04703d2a9 100644 --- a/_sips/sips/2018-07-31-interpolation-quote-escape.md +++ b/_sips/sips/2018-07-31-interpolation-quote-escape.md @@ -21,7 +21,7 @@ rather passes the raw string to the interpolator, which then has the option to process escapes itself as it sees fit. That means there are no lexing rules that process the escape, and the sequence `\"` simply terminates the interpolation. -Interpolations have a different meta-charcter -- the `$` character -- which is +Interpolations have a different meta-character -- the `$` character -- which is treated specially. Interpolations use this escape to splice in arguments, and it can also be used to escape itself as the sequence `$$` to represent a literal `$` character. @@ -90,7 +90,7 @@ on the original ticket ## Implementation The implementation is simple to the point of being trivial: see -[the implementation][5] for the actual change in functonality and the rest of +[the implementation][5] for the actual change in functionality and the rest of that PR for the spec and test changes. ## Drawbacks @@ -101,12 +101,12 @@ the language. An argument could be made that this change makes that worse rather than better. Because it affects parsing, this change may affect syntax highlighters. Syntax -highlighters tend to already stuggle around "funky" strings and interpolations. +highlighters tend to already struggle around "funky" strings and interpolations. ## Alternatives More ambitious proposals around interpolations are possible, and have been -propsed in different forms before. [This PR][6] in particular shows more options +proposed in different forms before. [This PR][6] in particular shows more options around using `\` as a meta character in interpolations. It stranded somewhere between red tape, ambition and changing processes. diff --git a/_tour/automatic-closures.md b/_tour/automatic-closures.md index 37b82524ef..e65c7130af 100644 --- a/_tour/automatic-closures.md +++ b/_tour/automatic-closures.md @@ -7,7 +7,7 @@ discourse: true partof: scala-tour --- -Scala allows parameterless function names as parameters of methods. When such a method is called, the actual parameters for parameterless function names are not evaluated and a nullary function is passed instead which encapsulates the computation of the corresponding parameter (so-called *call-by-name* evalutation). +Scala allows parameterless function names as parameters of methods. When such a method is called, the actual parameters for parameterless function names are not evaluated and a nullary function is passed instead which encapsulates the computation of the corresponding parameter (so-called *call-by-name* evaluation). The following code demonstrates this mechanism: diff --git a/_tour/traits.md b/_tour/traits.md index 121255457d..37bf615c6c 100644 --- a/_tour/traits.md +++ b/_tour/traits.md @@ -45,7 +45,7 @@ trait Iterator[A] { class IntIterator(to: Int) extends Iterator[Int] { private var current = 0 override def hasNext: Boolean = current < to - override def next(): Int = { + override def next(): Int = { if (hasNext) { val t = current current += 1 diff --git a/contribute.md b/contribute.md index 9f4692f679..5f4c2b6850 100644 --- a/contribute.md +++ b/contribute.md @@ -79,7 +79,7 @@ If you have something you're thinking about contributing, or that you're thinkin ### Guides/Overviews -A guide or an overview that can be logically placed on **one** page must be placed in the directory `overviews/RELEVANT-CATEGORY/_posts` with the file name in the format `YYYY-MM-dd-title-separarted-by-dashes.md`, and header: +A guide or an overview that can be logically placed on **one** page must be placed in the directory `overviews/RELEVANT-CATEGORY/_posts` with the file name in the format `YYYY-MM-dd-title-separated-by-dashes.md`, and header: --- layout: overview diff --git a/getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.md b/getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.md index 74bfff8b5b..021aed1bbf 100644 --- a/getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.md +++ b/getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.md @@ -19,11 +19,11 @@ Started with Scala and sbt on the Command Line]({{site.baseurl}}/getting-started here to the section "Writing Scala code". 1. If you didn't create the project from the command line, open up IntelliJ and select "Create New Project" - * On the left panel, select Scala and on the right panel, select SBT + * On the left panel, select Scala and on the right panel, select sbt * Click **Next** - * Name the project "SBTExampleProject" + * Name the project "SbtExampleProject" 1. If you already created the project on the command line, open up IntelliJ, select *Import Project* and open the `build.sbt` file for your project -1. Make sure the **JDK Version** is 1.8 and the **SBT Version** is at least 0.13.13 +1. Make sure the **JDK version** is 1.8 and the **sbt version** is at least 0.13.13 1. Select **Use auto-import** so dependencies are automatically downloaded when available 1. Select **Finish** @@ -47,7 +47,7 @@ but here's a glance at what everything is for: ## Writing Scala code -1. On the **Project** panel on the left, expand `SBTExampleProject` => `src` +1. On the **Project** panel on the left, expand `SbtExampleProject` => `src` => `main` 1. Right-click `scala` and select **New** => **Package** 1. Name the package `example` and click **OK**. @@ -68,9 +68,9 @@ to see if sbt can run your project on the command line. ## Running the project 1. From the **Run** menu, select **Edit configurations** -1. Click the **+** button and select **SBT Task**. +1. Click the **+** button and select **sbt Task**. 1. Name it `Run the program`. -1. In the **Tasks** field, type `~run`. The `~` causes SBT to rebuild and rerun the project +1. In the **Tasks** field, type `~run`. The `~` causes sbt to rebuild and rerun the project when you save changes to a file in the project. 1. Click **OK**. 1. On the **Run** menu. Click **Run 'Run the program'**. diff --git a/getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.md b/getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.md index 388f76a1de..ba38a030ee 100644 --- a/getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.md +++ b/getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.md @@ -20,9 +20,9 @@ We assume you know [how to create a Scala project with sbt](getting-started-with ``` sbt test -[info] Loading global plugins from /Users/travislee/.sbt/0.13/plugins -[info] Loading project definition from /Users/travislee/workspace/sandbox/my-something-project/project -[info] Set current project to scalatest-example (in build file:/Users/travislee/workspace/sandbox/my-something-project/) +[info] Loading global plugins from /Users/username/.sbt/0.13/plugins +[info] Loading project definition from /Users/username/workspace/sandbox/my-something-project/project +[info] Set current project to scalatest-example (in build file:/Users/username/workspace/sandbox/my-something-project/) [info] CubeCalculatorTest: [info] - CubeCalculator.cube [info] Run completed in 267 milliseconds. diff --git a/news/_posts/2012-12-12-functional-programming-principles-in-scala-impressions-and-statistics.md b/news/_posts/2012-12-12-functional-programming-principles-in-scala-impressions-and-statistics.md index 7735015903..60c52a7875 100644 --- a/news/_posts/2012-12-12-functional-programming-principles-in-scala-impressions-and-statistics.md +++ b/news/_posts/2012-12-12-functional-programming-principles-in-scala-impressions-and-statistics.md @@ -6,7 +6,7 @@ discourse: true ###### By Heather Miller and Martin Odersky
- In this post, we discuss our experience giving the popular MOOC Functional Programming Principles in Scala, and provide some insight into who our course participants were, how, overall, students performed in the course, and how students felt about the course. We visualize a lot of these statistics in a number of interactive plots, and we go on to publicly release the data and the code to generate these plots within a fun Scala-based project aimed at allowing you to manipulate these statistics with functional programming in Scala, to generate HTML/Javascript for easily visualizing and sharing them. We encourage you to share what you find with us— we'll share a number of your plots in a follow-up post! + In this post, we discuss our experience giving the popular MOOC Functional Programming Principles in Scala, and provide some insight into who our course participants were, how, overall, students performed in the course, and how students felt about the course. We visualize a lot of these statistics in a number of interactive plots, and we go on to publicly release the data and the code to generate these plots within a fun Scala-based project aimed at allowing you to manipulate these statistics with functional programming in Scala, to generate HTML/JavaScript for easily visualizing and sharing them. We encourage you to share what you find with us— we'll share a number of your plots in a follow-up post!
[_Functional Programming Principles in Scala_](https://www.coursera.org/course/progfun) is a [MOOC](http://en.wikipedia.org/wiki/Massive_open_online_course) given by [our research group](http://lamp.epfl.ch) at [EPFL](http://www.epfl.ch), whose first edition was recently completed on [Coursera](http://www.coursera.org). The certificates of completion for those who passed the course have been released, and in looking back as the dust settles— it was a great experience to have done a class like that which greatly exceeded our expectations in more than one dimension. diff --git a/resources/images/library-author-guide/fowards_backwards_compatibility.png b/resources/images/library-author-guide/forward_backward_compatibility.png similarity index 100% rename from resources/images/library-author-guide/fowards_backwards_compatibility.png rename to resources/images/library-author-guide/forward_backward_compatibility.png From 557caf9adb45b7b84b1072cc603964ffbee2a9c3 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Mon, 10 Jun 2019 15:43:32 +0200 Subject: [PATCH 0505/3075] Update representation of un-evaluated collections as per scala/scala#8029 --- .../concrete-immutable-collection-classes.md | 4 ++-- _overviews/collections-2.13/views.md | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/_overviews/collections-2.13/concrete-immutable-collection-classes.md b/_overviews/collections-2.13/concrete-immutable-collection-classes.md index e3c8f68556..131295bf0f 100644 --- a/_overviews/collections-2.13/concrete-immutable-collection-classes.md +++ b/_overviews/collections-2.13/concrete-immutable-collection-classes.md @@ -25,7 +25,7 @@ A [LazyList](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/co Whereas lists are constructed with the `::` operator, lazy lists are constructed with the similar-looking `#::`. Here is a simple example of a lazy list containing the integers 1, 2, and 3: scala> val lazyList = 1 #:: 2 #:: 3 #:: LazyList.empty - lazyList: scala.collection.immutable.LazyList[Int] = LazyList(?) + lazyList: scala.collection.immutable.LazyList[Int] = LazyList() The head of this lazy list is 1, and the tail of it has 2 and 3. None of the elements are printed here, though, because the list hasn’t been computed yet! Lazy lists are specified to compute lazily, and the `toString` method of a lazy list is careful not to force any extra evaluation. @@ -40,7 +40,7 @@ This function is deceptively simple. The first element of the sequence is clearl Here are the first few elements of the Fibonacci sequence starting with two ones: scala> val fibs = fibFrom(1, 1).take(7) - fibs: scala.collection.immutable.LazyList[Int] = LazyList(?) + fibs: scala.collection.immutable.LazyList[Int] = LazyList() scala> fibs.toList res9: List[Int] = List(1, 1, 2, 3, 5, 8, 13) diff --git a/_overviews/collections-2.13/views.md b/_overviews/collections-2.13/views.md index a9ec4c3d25..61ebae3cef 100644 --- a/_overviews/collections-2.13/views.md +++ b/_overviews/collections-2.13/views.md @@ -46,20 +46,20 @@ In the last statement, the expression `v map (_ + 1)` constructs a new vector wh Let's do this sequence of operations again, one by one: scala> val vv = v.view - vv: scala.collection.IndexedSeqView[Int] = View(?) + vv: scala.collection.IndexedSeqView[Int] = IndexedSeqView() The application `v.view` gives you an `IndexedSeqView[Int]`, i.e. a lazily evaluated `IndexedSeq[Int]`. Like with `LazyList`, -the `toString` operation of views does not force the view elements, that’s why the content of `vv` is shown as `View(?)`. +the `toString` operation of views does not force the view elements, that’s why the content of `vv` is shown as `IndexedSeqView()`. Applying the first `map` to the view gives: scala> vv map (_ + 1) - res13: scala.collection.IndexedSeqView[Int] = View(?) + res13: scala.collection.IndexedSeqView[Int] = IndexedSeqView() The result of the `map` is another `IndexedSeqView[Int]` value. This is in essence a wrapper that *records* the fact that a `map` with function `(_ + 1)` needs to be applied on the vector `v`. It does not apply that map until the view is forced, however. Let's now apply the second `map` to the last result. scala> res13 map (_ * 2) - res14: scala.collection.IndexedSeqView[Int] = View(?) + res14: scala.collection.IndexedSeqView[Int] = IndexedSeqView() Finally, forcing the last result gives: From e56ed6502486f58935cb08f2a663535890d287b4 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Mon, 10 Jun 2019 22:34:04 +0200 Subject: [PATCH 0506/3075] update 2.13 collections intro --- _overviews/collections-2.13/introduction.md | 46 ++++++++++----------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/_overviews/collections-2.13/introduction.md b/_overviews/collections-2.13/introduction.md index 2f077f3383..a4ff432874 100644 --- a/_overviews/collections-2.13/introduction.md +++ b/_overviews/collections-2.13/introduction.md @@ -12,22 +12,15 @@ num: 1 permalink: /overviews/collections-2.13/:title.html --- -**Martin Odersky, and Lex Spoon** - -In the eyes of many, the new collections framework is the most significant -change in the Scala 2.8 release. Scala had collections before (and in fact the new -framework is largely compatible with them). But it's only 2.8 that -provides a common, uniform, and all-encompassing framework for -collection types. - -Even though the additions to collections are subtle at first glance, -the changes they can provoke in your programming style can be -profound. In fact, quite often it's as if you work on a higher-level -with the basic building blocks of a program being whole collections -instead of their elements. This new style of programming requires some -adaptation. Fortunately, the adaptation is helped by several nice -properties of the new Scala collections. They are easy to use, -concise, safe, fast, universal. +The collections framework is the heart of the Scala 2.13 standard +library. It provides a common, uniform, and all-encompassing +framework for collection types. This framework enables you to work +with data in memory at a high level, with the basic building blocks of +a program being whole collections, instead of individual elements. + +This style of programming requires some learning. Fortunately, +the adaptation is helped by several nice properties of the Scala +collections. They are easy to use, concise, safe, fast, universal. **Easy to use:** A small vocabulary of 20-50 methods is enough to solve most collection problems in a couple of operations. No @@ -40,7 +33,7 @@ collection updates is eliminated. **Concise:** You can achieve with a single word what used to take one or several loops. You can express functional operations with lightweight syntax and combine operations effortlessly, so that the result -feels like a custom algebra. +feels like a custom algebra. **Safe:** This one has to be experienced to sink in. The statically typed and functional nature of Scala's collections means @@ -59,10 +52,13 @@ libraries. As a result, using collections is typically quite efficient. You might be able to do a little bit better with carefully hand-tuned data structures and operations, but you might also do a lot worse by making some suboptimal implementation decisions along the -way. What's more, collections have been recently adapted to parallel -execution on multi-cores. Parallel collections support the same -operations as sequential ones, so no new operations need to be learned -and no code needs to be rewritten. You can turn a sequential collection into a +way. + +**Parallel**: The +[`scala-parallel-collections` module](https://index.scala-lang.org/scala/scala-parallel-collections/scala-parallel-collections) +provides parallel execution of collections operations across multiple cores. +Parallel collections generally support the same +operations as sequential ones. You can turn a sequential collection into a parallel one simply by invoking the `par` method. **Universal:** Collections provide the same operations on @@ -89,10 +85,10 @@ traditional collection processing (three loops for an array, because the intermediate results need to be buffered somewhere else). Once you have learned the basic collection vocabulary you will also find writing this code is much easier and safer than writing explicit -loops. Furthermore, the `partition` operation is quite fast, and can -be even faster on parallel collections on multi-cores. (Parallel -collections are available as a -[separate library](https://index.scala-lang.org/scala/scala-parallel-collections/scala-parallel-collections)) +loops. + +Furthermore, the `partition` operation is quite fast, and can +be even faster on parallel collections on multiple cores. This document provides an in depth discussion of the APIs of the Scala collections classes from a user perspective. It takes you on From c95cb8f2f4577e845853784f0cbc0d4ea09184c3 Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Tue, 11 Jun 2019 10:14:11 +0800 Subject: [PATCH 0507/3075] Fix issue#1361, add space for markdown syntax enclosing . --- glossary/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glossary/index.md b/glossary/index.md index 3b638f3a46..ca50ce5486 100644 --- a/glossary/index.md +++ b/glossary/index.md @@ -195,7 +195,7 @@ Meta-programming software is software whose input is itself software. Compilers A _method_ is a function that is a member of some class, trait, or singleton object. * #### mixin -_Mixin_ is what a trait is called when it is being used in a mixin composition. In other words, in “`trait Hat`,” `Hat` is just a trait, but in “`new Cat extends AnyRef with Hat`,” `Hat` can be called a mixin. When used as a verb, “mix in” is two words. For example, you can _mix_ traits _in_to classes or other traits. +_Mixin_ is what a trait is called when it is being used in a mixin composition. In other words, in “`trait Hat`,” `Hat` is just a trait, but in “`new Cat extends AnyRef with Hat`,” `Hat` can be called a mixin. When used as a verb, “mix in” is two words. For example, you can _mix_ traits _in_ to classes or other traits. * #### mixin composition The process of mixing traits into classes or other traits. _Mixin composition_ differs from traditional multiple inheritance in that the type of the super reference is not known at the point the trait is defined, but rather is determined anew each time the trait is mixed into a class or other trait. From 4998f619855df3accd6d6409a42c0cc300148a48 Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Tue, 11 Jun 2019 12:22:24 +0800 Subject: [PATCH 0508/3075] Fix issue#1363, remove - and space within defined. --- glossary/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glossary/index.md b/glossary/index.md index 3b638f3a46..ba2382b2ac 100644 --- a/glossary/index.md +++ b/glossary/index.md @@ -216,7 +216,7 @@ In Scala, every _operation_ is a method call. Methods may be invoked in _operato Functions may take zero to many _parameters_. Each parameter has a name and a type. The distinction between parameters and arguments is that arguments refer to the actual objects passed when a function is invoked. Parameters are the variables that refer to those passed arguments. * #### parameterless function -A function that takes no parameters, which is de- fined without any empty parentheses. Invocations of parameterless functions may not supply parentheses. This supports the [uniform access principle](#uniform-access-principle), which enables the `def` to be changed into a `val` without requiring a change to client code. +A function that takes no parameters, which is defined without any empty parentheses. Invocations of parameterless functions may not supply parentheses. This supports the [uniform access principle](#uniform-access-principle), which enables the `def` to be changed into a `val` without requiring a change to client code. * #### parameterless method A _parameterless method_ is a parameterless function that is a member of a class, trait, or singleton object. From 978b9b07ed0d981b7967cf0fe0bcdb81ddf0b27d Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Mon, 10 Jun 2019 13:45:16 +0200 Subject: [PATCH 0509/3075] Scala 2.13 release --- _config.yml | 4 +-- .../concrete-immutable-collection-classes.md | 22 ++++++++-------- .../concrete-mutable-collection-classes.md | 22 ++++++++-------- _overviews/collections-2.13/iterators.md | 6 ++--- _overviews/collections-2.13/overview.md | 8 +++--- _overviews/collections-2.13/trait-iterable.md | 4 +-- _overviews/collections/arrays.md | 2 +- .../concrete-immutable-collection-classes.md | 20 +++++++------- .../concrete-mutable-collection-classes.md | 26 +++++++++---------- ...ions-between-java-and-scala-collections.md | 4 +-- _overviews/collections/iterators.md | 6 ++--- .../concrete-parallel-collections.md | 22 ++++++++-------- api/all.md | 6 +++++ 13 files changed, 79 insertions(+), 73 deletions(-) diff --git a/_config.yml b/_config.yml index 32288ccccc..e7564efd1a 100644 --- a/_config.yml +++ b/_config.yml @@ -15,8 +15,8 @@ keywords: - Document - Guide -scala-version: 2.12.8 -scala-213-version: 2.13.0-M5 +scala-version: 2.13.0 +scala-212-version: 2.12.8 collections: style: diff --git a/_overviews/collections-2.13/concrete-immutable-collection-classes.md b/_overviews/collections-2.13/concrete-immutable-collection-classes.md index e3c8f68556..af8ed0b95c 100644 --- a/_overviews/collections-2.13/concrete-immutable-collection-classes.md +++ b/_overviews/collections-2.13/concrete-immutable-collection-classes.md @@ -16,11 +16,11 @@ Scala provides many concrete immutable collection classes for you to choose from ## Lists -A [List](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/List.html) is a finite immutable sequence. They provide constant-time access to their first element as well as the rest of the list, and they have a constant-time cons operation for adding a new element to the front of the list. Many other operations take linear time. +A [List](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/List.html) is a finite immutable sequence. They provide constant-time access to their first element as well as the rest of the list, and they have a constant-time cons operation for adding a new element to the front of the list. Many other operations take linear time. ## LazyLists -A [LazyList](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/LazyList.html) is like a list except that its elements are computed lazily. Because of this, a lazy list can be infinitely long. Only those elements requested are computed. Otherwise, lazy lists have the same performance characteristics as lists. +A [LazyList](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/LazyList.html) is like a list except that its elements are computed lazily. Because of this, a lazy list can be infinitely long. Only those elements requested are computed. Otherwise, lazy lists have the same performance characteristics as lists. Whereas lists are constructed with the `::` operator, lazy lists are constructed with the similar-looking `#::`. Here is a simple example of a lazy list containing the integers 1, 2, and 3: @@ -48,7 +48,7 @@ Here are the first few elements of the Fibonacci sequence starting with two ones Lists are very efficient when the algorithm processing them is careful to only process their heads. Accessing, adding, and removing the head of a list takes only constant time, whereas accessing or modifying elements later in the list takes time linear in the depth into the list. -[ArraySeq](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/ArraySeq.html) is a +[ArraySeq](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/ArraySeq.html) is a collection type (introduced in Scala 2.13) that addresses the inefficiency for random access on lists. ArraySeqs allow accessing any element of the collection in constant time. As a result, algorithms using ArraySeqs do not have to be careful about accessing just the head of the collection. They can access elements at arbitrary locations, @@ -87,7 +87,7 @@ We have seen in the previous sections that `List` and `ArraySeq` are efficient d use cases but they are also inefficient in other use cases: for instance, prepending an element is constant for `List`, but linear for `ArraySeq`, and, conversely, indexed access is constant for `ArraySeq` but linear for `List`. -[Vector](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/Vector.html) is a collection type that provides good performance for all its operations. Vectors allow accessing any element of the sequence in "effectively" constant time. It's a larger constant than for access to the head of a List or for reading an element of an ArraySeq, but it's a constant nonetheless. As a result, algorithms using vectors do not have to be careful about accessing just the head of the sequence. They can access and modify elements at arbitrary locations, and thus they can be much more convenient to write. +[Vector](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Vector.html) is a collection type that provides good performance for all its operations. Vectors allow accessing any element of the sequence in "effectively" constant time. It's a larger constant than for access to the head of a List or for reading an element of an ArraySeq, but it's a constant nonetheless. As a result, algorithms using vectors do not have to be careful about accessing just the head of the sequence. They can access and modify elements at arbitrary locations, and thus they can be much more convenient to write. Vectors are built and modified just like any other sequence. @@ -112,7 +112,7 @@ Because vectors strike a good balance between fast random selections and fast ra ## Immutable Queues -A [Queue](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/Queue.html) is a first-in-first-out sequence. You enqueue an element onto a queue with `enqueue`, and dequeue an element with `dequeue`. These operations are constant time. +A [Queue](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Queue.html) is a first-in-first-out sequence. You enqueue an element onto a queue with `enqueue`, and dequeue an element with `dequeue`. These operations are constant time. Here's how you can create an empty immutable queue: @@ -140,7 +140,7 @@ Note that `dequeue` returns a pair consisting of the element removed and the res ## Ranges -A [Range](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/Range.html) is an ordered sequence of integers that are equally spaced apart. For example, "1, 2, 3," is a range, as is "5, 8, 11, 14." To create a range in Scala, use the predefined methods `to` and `by`. +A [Range](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Range.html) is an ordered sequence of integers that are equally spaced apart. For example, "1, 2, 3," is a range, as is "5, 8, 11, 14." To create a range in Scala, use the predefined methods `to` and `by`. scala> 1 to 3 res2: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3) @@ -156,7 +156,7 @@ Ranges are represented in constant space, because they can be defined by just th ## Compressed Hash-Array Mapped Prefix-trees -Hash tries are a standard way to implement immutable sets and maps efficiently. [Compressed Hash-Array Mapped Prefix-trees](https://github.com/msteindorfer/oopsla15-artifact/) are a design for hash tries on the JVM which improves locality and makes sure the trees remain in a canonical and compact representation. They are supported by class [immutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/HashMap.html). Their representation is similar to vectors in that they are also trees where every node has 32 elements or 32 subtrees. But the selection of these keys is now done based on hash code. For instance, to find a given key in a map, one first takes the hash code of the key. Then, the lowest 5 bits of the hash code are used to select the first subtree, followed by the next 5 bits and so on. The selection stops once all elements stored in a node have hash codes that differ from each other in the bits that are selected up to this level. +Hash tries are a standard way to implement immutable sets and maps efficiently. [Compressed Hash-Array Mapped Prefix-trees](https://github.com/msteindorfer/oopsla15-artifact/) are a design for hash tries on the JVM which improves locality and makes sure the trees remain in a canonical and compact representation. They are supported by class [immutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/HashMap.html). Their representation is similar to vectors in that they are also trees where every node has 32 elements or 32 subtrees. But the selection of these keys is now done based on hash code. For instance, to find a given key in a map, one first takes the hash code of the key. Then, the lowest 5 bits of the hash code are used to select the first subtree, followed by the next 5 bits and so on. The selection stops once all elements stored in a node have hash codes that differ from each other in the bits that are selected up to this level. Hash tries strike a nice balance between reasonably fast lookups and reasonably efficient functional insertions (`+`) and deletions (`-`). That's why they underly Scala's default implementations of immutable maps and sets. In fact, Scala has a further optimization for immutable sets and maps that contain less than five elements. Sets and maps with one to four elements are stored as single objects that just contain the elements (or key/value pairs in the case of a map) as fields. The empty immutable set and the empty immutable map is in each case a single object - there's no need to duplicate storage for those because an empty immutable set or map will always stay empty. @@ -164,7 +164,7 @@ Hash tries strike a nice balance between reasonably fast lookups and reasonably Red-black trees are a form of balanced binary tree where some nodes are designated "red" and others designated "black." Like any balanced binary tree, operations on them reliably complete in time logarithmic to the size of the tree. -Scala provides implementations of immutable sets and maps that use a red-black tree internally. Access them under the names [TreeSet](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/TreeSet.html) and [TreeMap](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/TreeMap.html). +Scala provides implementations of immutable sets and maps that use a red-black tree internally. Access them under the names [TreeSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/TreeSet.html) and [TreeMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/TreeMap.html). scala> scala.collection.immutable.TreeSet.empty[Int] @@ -176,7 +176,7 @@ Red-black trees are the standard implementation of `SortedSet` in Scala, because ## Immutable BitSets -A [BitSet](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/BitSet.html) represents a collection of small integers as the bits of a larger integer. For example, the bit set containing 3, 2, and 0 would be represented as the integer 1101 in binary, which is 13 in decimal. +A [BitSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/BitSet.html) represents a collection of small integers as the bits of a larger integer. For example, the bit set containing 3, 2, and 0 would be represented as the integer 1101 in binary, which is 13 in decimal. Internally, bit sets use an array of 64-bit `Long`s. The first `Long` in the array is for integers 0 through 63, the second is for 64 through 127, and so on. Thus, bit sets are very compact so long as the largest integer in the set is less than a few hundred or so. @@ -193,7 +193,7 @@ Operations on bit sets are very fast. Testing for inclusion takes constant time. ## VectorMaps -A [VectorMap](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/VectorMap.html) represents +A [VectorMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/VectorMap.html) represents a map using both a `Vector` of keys and a `HashMap`. It provides an iterator that returns all the entries in their insertion order. @@ -217,7 +217,7 @@ order of elements into account. ## ListMaps -A [ListMap](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/ListMap.html) represents a map as a linked list of key-value pairs. In general, operations on a list map might have to iterate through the entire list. Thus, operations on a list map take time linear in the size of the map. In fact there is little usage for list maps in Scala because standard immutable maps are almost always faster. The only possible exception to this is if the map is for some reason constructed in such a way that the first elements in the list are selected much more often than the other elements. +A [ListMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/ListMap.html) represents a map as a linked list of key-value pairs. In general, operations on a list map might have to iterate through the entire list. Thus, operations on a list map take time linear in the size of the map. In fact there is little usage for list maps in Scala because standard immutable maps are almost always faster. The only possible exception to this is if the map is for some reason constructed in such a way that the first elements in the list are selected much more often than the other elements. scala> val map = scala.collection.immutable.ListMap(1->"one", 2->"two") map: scala.collection.immutable.ListMap[Int,java.lang.String] = diff --git a/_overviews/collections-2.13/concrete-mutable-collection-classes.md b/_overviews/collections-2.13/concrete-mutable-collection-classes.md index bcf855ddc6..f2cf39eb41 100644 --- a/_overviews/collections-2.13/concrete-mutable-collection-classes.md +++ b/_overviews/collections-2.13/concrete-mutable-collection-classes.md @@ -16,7 +16,7 @@ You've now seen the most commonly used immutable collection classes that Scala p ## Array Buffers -An [ArrayBuffer](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/ArrayBuffer.html) buffer holds an array and a size. Most operations on an array buffer have the same speed as for an array, because the operations simply access and modify the underlying array. Additionally, array buffers can have data efficiently added to the end. Appending an item to an array buffer takes amortized constant time. Thus, array buffers are useful for efficiently building up a large collection whenever the new items are always added to the end. +An [ArrayBuffer](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ArrayBuffer.html) buffer holds an array and a size. Most operations on an array buffer have the same speed as for an array, because the operations simply access and modify the underlying array. Additionally, array buffers can have data efficiently added to the end. Appending an item to an array buffer takes amortized constant time. Thus, array buffers are useful for efficiently building up a large collection whenever the new items are always added to the end. scala> val buf = scala.collection.mutable.ArrayBuffer.empty[Int] buf: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer() @@ -29,7 +29,7 @@ An [ArrayBuffer](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scal ## List Buffers -A [ListBuffer](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/ListBuffer.html) is like an array buffer except that it uses a linked list internally instead of an array. If you plan to convert the buffer to a list once it is built up, use a list buffer instead of an array buffer. +A [ListBuffer](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ListBuffer.html) is like an array buffer except that it uses a linked list internally instead of an array. If you plan to convert the buffer to a list once it is built up, use a list buffer instead of an array buffer. scala> val buf = scala.collection.mutable.ListBuffer.empty[Int] buf: scala.collection.mutable.ListBuffer[Int] = ListBuffer() @@ -42,7 +42,7 @@ A [ListBuffer](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/ ## StringBuilders -Just like an array buffer is useful for building arrays, and a list buffer is useful for building lists, a [StringBuilder](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/StringBuilder.html) is useful for building strings. String builders are so commonly used that they are already imported into the default namespace. Create them with a simple `new StringBuilder`, like this: +Just like an array buffer is useful for building arrays, and a list buffer is useful for building lists, a [StringBuilder](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/StringBuilder.html) is useful for building strings. String builders are so commonly used that they are already imported into the default namespace. Create them with a simple `new StringBuilder`, like this: scala> val buf = new StringBuilder buf: StringBuilder = @@ -55,7 +55,7 @@ Just like an array buffer is useful for building arrays, and a list buffer is us ## ArrayDeque -An [ArrayDeque](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/ArrayDeque.html) +An [ArrayDeque](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ArrayDeque.html) is a sequence that supports efficient addition of elements in the front and in the end. It internally uses a resizable array. @@ -81,7 +81,7 @@ Scala provides mutable queues in addition to immutable ones. You use a `mQueue` ## Stacks -You saw immutable stacks earlier. There is also a mutable version, supported by class [mutable.Stack](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/Stack.html). It works exactly the same as the immutable version except that modifications happen in place. +You saw immutable stacks earlier. There is also a mutable version, supported by class [mutable.Stack](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/Stack.html). It works exactly the same as the immutable version except that modifications happen in place. scala> val stack = new scala.collection.mutable.Stack[Int] stack: scala.collection.mutable.Stack[Int] = Stack() @@ -104,13 +104,13 @@ You saw immutable stacks earlier. There is also a mutable version, supported by ## Mutable ArraySeqs -Array sequences are mutable sequences of fixed size which store their elements internally in an `Array[Object]`. They are implemented in Scala by class [ArraySeq](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/ArraySeq.html). +Array sequences are mutable sequences of fixed size which store their elements internally in an `Array[Object]`. They are implemented in Scala by class [ArraySeq](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ArraySeq.html). You would typically use an `ArraySeq` if you want an array for its performance characteristics, but you also want to create generic instances of the sequence where you do not know the type of the elements and you do not have a `ClassTag` to provide it at run-time. These issues are explained in the section on [arrays]({{ site.baseurl }}/overviews/collections/arrays.html). ## Hash Tables -A hash table stores its elements in an underlying array, placing each item at a position in the array determined by the hash code of that item. Adding an element to a hash table takes only constant time, so long as there isn't already another element in the array that has the same hash code. Hash tables are thus very fast so long as the objects placed in them have a good distribution of hash codes. As a result, the default mutable map and set types in Scala are based on hash tables. You can access them also directly under the names [mutable.HashSet](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/HashSet.html) and [mutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/HashMap.html). +A hash table stores its elements in an underlying array, placing each item at a position in the array determined by the hash code of that item. Adding an element to a hash table takes only constant time, so long as there isn't already another element in the array that has the same hash code. Hash tables are thus very fast so long as the objects placed in them have a good distribution of hash codes. As a result, the default mutable map and set types in Scala are based on hash tables. You can access them also directly under the names [mutable.HashSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/HashSet.html) and [mutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/HashMap.html). Hash sets and maps are used just like any other set or map. Here are some simple examples: @@ -129,11 +129,11 @@ Iteration over a hash table is not guaranteed to occur in any particular order. ## Weak Hash Maps -A weak hash map is a special kind of hash map where the garbage collector does not follow links from the map to the keys stored in it. This means that a key and its associated value will disappear from the map if there is no other reference to that key. Weak hash maps are useful for tasks such as caching, where you want to re-use an expensive function's result if the function is called again on the same key. If keys and function results are stored in a regular hash map, the map could grow without bounds, and no key would ever become garbage. Using a weak hash map avoids this problem. As soon as a key object becomes unreachable, it's entry is removed from the weak hashmap. Weak hash maps in Scala are implemented by class [WeakHashMap](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/WeakHashMap.html) as a wrapper of an underlying Java implementation `java.util.WeakHashMap`. +A weak hash map is a special kind of hash map where the garbage collector does not follow links from the map to the keys stored in it. This means that a key and its associated value will disappear from the map if there is no other reference to that key. Weak hash maps are useful for tasks such as caching, where you want to re-use an expensive function's result if the function is called again on the same key. If keys and function results are stored in a regular hash map, the map could grow without bounds, and no key would ever become garbage. Using a weak hash map avoids this problem. As soon as a key object becomes unreachable, it's entry is removed from the weak hashmap. Weak hash maps in Scala are implemented by class [WeakHashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/WeakHashMap.html) as a wrapper of an underlying Java implementation `java.util.WeakHashMap`. ## Concurrent Maps -A concurrent map can be accessed by several threads at once. In addition to the usual [Map](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Map.html) operations, it provides the following atomic operations: +A concurrent map can be accessed by several threads at once. In addition to the usual [Map](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Map.html) operations, it provides the following atomic operations: ### Operations in Class concurrent.Map @@ -144,11 +144,11 @@ A concurrent map can be accessed by several threads at once. In addition to the | `m.replace(k, old, new)` |Replaces value associated with key `k` to `new`, if it was previously bound to `old`. | | `m.replace (k, v)` |Replaces value associated with key `k` to `v`, if it was previously bound to some value.| -`concurrent.Map` is a trait in the Scala collections library. Currently, it has two implementations. The first one is Java's `java.util.concurrent.ConcurrentMap`, which can be converted automatically into a Scala map using the [standard Java/Scala collection conversions]({{ site.baseurl }}/overviews/collections/conversions-between-java-and-scala-collections.html). The second implementation is [TrieMap](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/concurrent/TrieMap.html), which is a lock-free implementation of a hash array mapped trie. +`concurrent.Map` is a trait in the Scala collections library. Currently, it has two implementations. The first one is Java's `java.util.concurrent.ConcurrentMap`, which can be converted automatically into a Scala map using the [standard Java/Scala collection conversions]({{ site.baseurl }}/overviews/collections/conversions-between-java-and-scala-collections.html). The second implementation is [TrieMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/concurrent/TrieMap.html), which is a lock-free implementation of a hash array mapped trie. ## Mutable Bitsets -A mutable bit of type [mutable.BitSet](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/BitSet.html) set is just like an immutable one, except that it is modified in place. Mutable bit sets are slightly more efficient at updating than immutable ones, because they don't have to copy around `Long`s that haven't changed. +A mutable bit of type [mutable.BitSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/BitSet.html) set is just like an immutable one, except that it is modified in place. Mutable bit sets are slightly more efficient at updating than immutable ones, because they don't have to copy around `Long`s that haven't changed. scala> val bits = scala.collection.mutable.BitSet.empty bits: scala.collection.mutable.BitSet = BitSet() diff --git a/_overviews/collections-2.13/iterators.md b/_overviews/collections-2.13/iterators.md index 55de58cb7e..6d71f2bd1b 100644 --- a/_overviews/collections-2.13/iterators.md +++ b/_overviews/collections-2.13/iterators.md @@ -12,7 +12,7 @@ num: 15 permalink: /overviews/collections-2.13/:title.html --- -An iterator is not a collection, but rather a way to access the elements of a collection one by one. The two basic operations on an iterator `it` are `next` and `hasNext`. A call to `it.next()` will return the next element of the iterator and advance the state of the iterator. Calling `next` again on the same iterator will then yield the element one beyond the one returned previously. If there are no more elements to return, a call to `next` will throw a `NoSuchElementException`. You can find out whether there are more elements to return using [Iterator](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Iterator.html)'s `hasNext` method. +An iterator is not a collection, but rather a way to access the elements of a collection one by one. The two basic operations on an iterator `it` are `next` and `hasNext`. A call to `it.next()` will return the next element of the iterator and advance the state of the iterator. Calling `next` again on the same iterator will then yield the element one beyond the one returned previously. If there are no more elements to return, a call to `next` will throw a `NoSuchElementException`. You can find out whether there are more elements to return using [Iterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html)'s `hasNext` method. The most straightforward way to "step through" all the elements returned by an iterator `it` uses a while-loop: @@ -78,7 +78,7 @@ destructively modified by invoking arbitrary methods. This creates the illusion the elements twice, but the effect is achieved through internal buffering. As usual, the underlying iterator `it` cannot be used directly and must be discarded. -In summary, iterators behave like collections _if one never accesses an iterator again after invoking a method on it_. The Scala collection libraries make this explicit with an abstraction [IterableOnce](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/IterableOnce.html), which is a common superclass of [Iterable](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Iterable.html) and [Iterator](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Iterator.html). `IterableOnce[A]` only has two methods: `iterator: Iterator[A]` and `knownSize: Int`. If an `IterableOnce` object is in fact an `Iterator`, its `iterator` operation always returns itself, in its current state, but if it is an `Iterable`, its `iterator` operation always return a new `Iterator`. A common use case of `IterableOnce` is as an argument type for methods that can take either an iterator or a collection as argument. An example is the appending method `concat` in class `Iterable`. It takes an `IterableOnce` parameter, so you can append elements coming from either an iterator or a collection. +In summary, iterators behave like collections _if one never accesses an iterator again after invoking a method on it_. The Scala collection libraries make this explicit with an abstraction [IterableOnce](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/IterableOnce.html), which is a common superclass of [Iterable](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterable.html) and [Iterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html). `IterableOnce[A]` only has two methods: `iterator: Iterator[A]` and `knownSize: Int`. If an `IterableOnce` object is in fact an `Iterator`, its `iterator` operation always returns itself, in its current state, but if it is an `Iterable`, its `iterator` operation always return a new `Iterator`. A common use case of `IterableOnce` is as an argument type for methods that can take either an iterator or a collection as argument. An example is the appending method `concat` in class `Iterable`. It takes an `IterableOnce` parameter, so you can append elements coming from either an iterator or a collection. All operations on iterators are summarized below. @@ -189,7 +189,7 @@ Sometimes you want an iterator that can "look ahead", so that you can inspect th But looking at this code more closely, it's clear that this is wrong: The code will indeed skip leading empty strings, but it will also advance `it` past the first non-empty string! -The solution to this problem is to use a buffered iterator. Class [BufferedIterator](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/BufferedIterator.html) is a subclass of [Iterator](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Iterator.html), which provides one extra method, `head`. Calling `head` on a buffered iterator will return its first element but will not advance the iterator. Using a buffered iterator, skipping empty words can be written as follows. +The solution to this problem is to use a buffered iterator. Class [BufferedIterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/BufferedIterator.html) is a subclass of [Iterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html), which provides one extra method, `head`. Calling `head` on a buffered iterator will return its first element but will not advance the iterator. Using a buffered iterator, skipping empty words can be written as follows. def skipEmptyWords(it: BufferedIterator[String]) = while (it.head.isEmpty) { it.next() } diff --git a/_overviews/collections-2.13/overview.md b/_overviews/collections-2.13/overview.md index 79cb856cc3..a96995b662 100644 --- a/_overviews/collections-2.13/overview.md +++ b/_overviews/collections-2.13/overview.md @@ -40,10 +40,10 @@ mutable collection means you need to understand which code changes which collection when. A collection in package `scala.collection` can be either mutable or -immutable. For instance, [collection.IndexedSeq\[T\]](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/IndexedSeq.html) -is a superclass of both [collection.immutable.IndexedSeq\[T\]](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/IndexedSeq.html) +immutable. For instance, [collection.IndexedSeq\[T\]](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/IndexedSeq.html) +is a superclass of both [collection.immutable.IndexedSeq\[T\]](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/IndexedSeq.html) and -[collection.mutable.IndexedSeq\[T\]](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/IndexedSeq.html) +[collection.mutable.IndexedSeq\[T\]](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/IndexedSeq.html) Generally, the root collections in package `scala.collection` support transformation operations affecting the whole collection, the immutable @@ -92,7 +92,7 @@ can be accessed alternatively as // is always automatically imported Other types aliased are -[Iterable](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Iterable.html), [Seq](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/Seq.html), [IndexedSeq](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/IndexedSeq.html), [Iterator](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Iterator.html), [LazyList](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/LazyList.html), [Vector](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/Vector.html), [StringBuilder](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/mutable/StringBuilder.html), and [Range](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/immutable/Range.html). +[Iterable](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterable.html), [Seq](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Seq.html), [IndexedSeq](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/IndexedSeq.html), [Iterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html), [LazyList](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/LazyList.html), [Vector](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Vector.html), [StringBuilder](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/StringBuilder.html), and [Range](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Range.html). The following figure shows all collections in package `scala.collection`. These are all high-level abstract classes or traits, which diff --git a/_overviews/collections-2.13/trait-iterable.md b/_overviews/collections-2.13/trait-iterable.md index 3ae2ecfb99..e306f39f16 100644 --- a/_overviews/collections-2.13/trait-iterable.md +++ b/_overviews/collections-2.13/trait-iterable.md @@ -64,7 +64,7 @@ Two more methods exist in `Iterable` that return iterators: `grouped` and `slidi | `xs grouped size` |An iterator that yields fixed-sized "chunks" of this collection.| | `xs sliding size` |An iterator that yields a sliding fixed-sized window of elements in this collection.| | **Addition:** | | -| `xs concat ys`
(or `xs ++ ys`) |A collection consisting of the elements of both `xs` and `ys`. `ys` is a [IterableOnce](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/IterableOnce.html) collection, i.e., either an [Iterable](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Iterable.html) or an [Iterator](http://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Iterator.html).| +| `xs concat ys`
(or `xs ++ ys`) |A collection consisting of the elements of both `xs` and `ys`. `ys` is a [IterableOnce](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/IterableOnce.html) collection, i.e., either an [Iterable](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterable.html) or an [Iterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html).| | **Maps:** | | | `xs map f` |The collection obtained from applying the function f to every element in `xs`.| | `xs flatMap f` |The collection obtained from applying the collection-valued function `f` to every element in `xs` and concatenating the results.| @@ -141,7 +141,7 @@ Two more methods exist in `Iterable` that return iterators: `grouped` and `slidi | **Views:** | | | `xs.view` |Produces a view over `xs`.| -In the inheritance hierarchy below `Iterable` you find three traits: [Seq](https://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Seq.html), [Set](https://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Set.html), and [Map](https://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/Map.html). `Seq` and `Map` implement the [PartialFunction](https://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/PartialFunction.html) trait with its `apply` and `isDefinedAt` methods, each implemented differently. `Set` gets its `apply` method from [SetOps](https://www.scala-lang.org/api/{{ site.scala-213-version }}/scala/collection/SetOps.html). +In the inheritance hierarchy below `Iterable` you find three traits: [Seq](https://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Seq.html), [Set](https://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Set.html), and [Map](https://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Map.html). `Seq` and `Map` implement the [PartialFunction](https://www.scala-lang.org/api/{{ site.scala-version }}/scala/PartialFunction.html) trait with its `apply` and `isDefinedAt` methods, each implemented differently. `Set` gets its `apply` method from [SetOps](https://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/SetOps.html). For sequences, `apply` is positional indexing, where elements are always numbered from `0`. That is, `Seq(1, 2, 3)(1)` gives `2`. For sets, `apply` is a membership test. For instance, `Set('a', 'b', 'c')('b')` gives `true` whereas `Set()('a')` gives `false`. Finally for maps, `apply` is a selection. For instance, `Map('a' -> 1, 'b' -> 10, 'c' -> 100)('b')` gives `10`. diff --git a/_overviews/collections/arrays.md b/_overviews/collections/arrays.md index 512df5e432..343ebb1c74 100644 --- a/_overviews/collections/arrays.md +++ b/_overviews/collections/arrays.md @@ -13,7 +13,7 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- -[Array](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/Array.html) is a special kind of collection in Scala. On the one hand, Scala arrays correspond one-to-one to Java arrays. That is, a Scala array `Array[Int]` is represented as a Java `int[]`, an `Array[Double]` is represented as a Java `double[]` and a `Array[String]` is represented as a Java `String[]`. But at the same time, Scala arrays offer much more than their Java analogues. First, Scala arrays can be _generic_. That is, you can have an `Array[T]`, where `T` is a type parameter or abstract type. Second, Scala arrays are compatible with Scala sequences - you can pass an `Array[T]` where a `Seq[T]` is required. Finally, Scala arrays also support all sequence operations. Here's an example of this in action: +[Array](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/Array.html) is a special kind of collection in Scala. On the one hand, Scala arrays correspond one-to-one to Java arrays. That is, a Scala array `Array[Int]` is represented as a Java `int[]`, an `Array[Double]` is represented as a Java `double[]` and a `Array[String]` is represented as a Java `String[]`. But at the same time, Scala arrays offer much more than their Java analogues. First, Scala arrays can be _generic_. That is, you can have an `Array[T]`, where `T` is a type parameter or abstract type. Second, Scala arrays are compatible with Scala sequences - you can pass an `Array[T]` where a `Seq[T]` is required. Finally, Scala arrays also support all sequence operations. Here's an example of this in action: scala> val a1 = Array(1, 2, 3) a1: Array[Int] = Array(1, 2, 3) diff --git a/_overviews/collections/concrete-immutable-collection-classes.md b/_overviews/collections/concrete-immutable-collection-classes.md index 64bfb62655..b0e16eceb7 100644 --- a/_overviews/collections/concrete-immutable-collection-classes.md +++ b/_overviews/collections/concrete-immutable-collection-classes.md @@ -17,7 +17,7 @@ Scala provides many concrete immutable collection classes for you to choose from ## Lists -A [List](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/List.html) is a finite immutable sequence. They provide constant-time access to their first element as well as the rest of the list, and they have a constant-time cons operation for adding a new element to the front of the list. Many other operations take linear time. +A [List](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/List.html) is a finite immutable sequence. They provide constant-time access to their first element as well as the rest of the list, and they have a constant-time cons operation for adding a new element to the front of the list. Many other operations take linear time. Lists have always been the workhorse for Scala programming, so not much needs to be said about them here. The major change in 2.8 is that the `List` class together with its subclass `::` and its subobject `Nil` is now defined in package `scala.collection.immutable`, where it logically belongs. There are still aliases for `List`, `Nil`, and `::` in the `scala` package, so from a user perspective, lists can be accessed as before. @@ -25,7 +25,7 @@ Another change is that lists now integrate more closely into the collections fra ## Streams -A [Stream](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Stream.html) is like a list except that its elements are computed lazily. Because of this, a stream can be infinitely long. Only those elements requested are computed. Otherwise, streams have the same performance characteristics as lists. +A [Stream](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Stream.html) is like a list except that its elements are computed lazily. Because of this, a stream can be infinitely long. Only those elements requested are computed. Otherwise, streams have the same performance characteristics as lists. Whereas lists are constructed with the `::` operator, streams are constructed with the similar-looking `#::`. Here is a simple example of a stream containing the integers 1, 2, and 3: @@ -52,7 +52,7 @@ Here are the first few elements of the Fibonacci sequence starting with two ones Lists are very efficient when the algorithm processing them is careful to only process their heads. Accessing, adding, and removing the head of a list takes only constant time, whereas accessing or modifying elements later in the list takes time linear in the depth into the list. -[Vector](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Vector.html) is a collection type (introduced in Scala 2.8) that addresses the inefficiency for random access on lists. Vectors allow accessing any element of the list in "effectively" constant time. It's a larger constant than for access to the head of a list or for reading an element of an array, but it's a constant nonetheless. As a result, algorithms using vectors do not have to be careful about accessing just the head of the sequence. They can access and modify elements at arbitrary locations, and thus they can be much more convenient to write. +[Vector](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Vector.html) is a collection type (introduced in Scala 2.8) that addresses the inefficiency for random access on lists. Vectors allow accessing any element of the list in "effectively" constant time. It's a larger constant than for access to the head of a list or for reading an element of an array, but it's a constant nonetheless. As a result, algorithms using vectors do not have to be careful about accessing just the head of the sequence. They can access and modify elements at arbitrary locations, and thus they can be much more convenient to write. Vectors are built and modified just like any other sequence. @@ -86,7 +86,7 @@ Because vectors strike a good balance between fast random selections and fast ra ## Immutable stacks -If you need a last-in-first-out sequence, you can use a [Stack](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Stack.html). You push an element onto a stack with `push`, pop an element with `pop`, and peek at the top of the stack without removing it with `top`. All of these operations are constant time. +If you need a last-in-first-out sequence, you can use a [Stack](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Stack.html). You push an element onto a stack with `push`, pop an element with `pop`, and peek at the top of the stack without removing it with `top`. All of these operations are constant time. Here are some simple operations performed on a stack: @@ -106,7 +106,7 @@ Immutable stacks are used rarely in Scala programs because their functionality i ## Immutable Queues -A [Queue](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Queue.html) is just like a stack except that it is first-in-first-out rather than last-in-first-out. +A [Queue](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Queue.html) is just like a stack except that it is first-in-first-out rather than last-in-first-out. Here's how you can create an empty immutable queue: @@ -134,7 +134,7 @@ Note that `dequeue` returns a pair consisting of the element removed and the res ## Ranges -A [Range](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Range.html) is an ordered sequence of integers that are equally spaced apart. For example, "1, 2, 3," is a range, as is "5, 8, 11, 14." To create a range in Scala, use the predefined methods `to` and `by`. +A [Range](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Range.html) is an ordered sequence of integers that are equally spaced apart. For example, "1, 2, 3," is a range, as is "5, 8, 11, 14." To create a range in Scala, use the predefined methods `to` and `by`. scala> 1 to 3 res2: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3) @@ -150,7 +150,7 @@ Ranges are represented in constant space, because they can be defined by just th ## Hash Tries -Hash tries are a standard way to implement immutable sets and maps efficiently. They are supported by class [immutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/HashMap.html). Their representation is similar to vectors in that they are also trees where every node has 32 elements or 32 subtrees. But the selection of these keys is now done based on hash code. For instance, to find a given key in a map, one first takes the hash code of the key. Then, the lowest 5 bits of the hash code are used to select the first subtree, followed by the next 5 bits and so on. The selection stops once all elements stored in a node have hash codes that differ from each other in the bits that are selected up to this level. +Hash tries are a standard way to implement immutable sets and maps efficiently. They are supported by class [immutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/HashMap.html). Their representation is similar to vectors in that they are also trees where every node has 32 elements or 32 subtrees. But the selection of these keys is now done based on hash code. For instance, to find a given key in a map, one first takes the hash code of the key. Then, the lowest 5 bits of the hash code are used to select the first subtree, followed by the next 5 bits and so on. The selection stops once all elements stored in a node have hash codes that differ from each other in the bits that are selected up to this level. Hash tries strike a nice balance between reasonably fast lookups and reasonably efficient functional insertions (`+`) and deletions (`-`). That's why they underlie Scala's default implementations of immutable maps and sets. In fact, Scala has a further optimization for immutable sets and maps that contain less than five elements. Sets and maps with one to four elements are stored as single objects that just contain the elements (or key/value pairs in the case of a map) as fields. The empty immutable set and the empty immutable map is in each case a single object - there's no need to duplicate storage for those because an empty immutable set or map will always stay empty. @@ -158,7 +158,7 @@ Hash tries strike a nice balance between reasonably fast lookups and reasonably Red-black trees are a form of balanced binary tree where some nodes are designated "red" and others designated "black." Like any balanced binary tree, operations on them reliably complete in time logarithmic to the size of the tree. -Scala provides implementations of immutable sets and maps that use a red-black tree internally. Access them under the names [TreeSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/TreeSet.html) and [TreeMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/TreeMap.html). +Scala provides implementations of immutable sets and maps that use a red-black tree internally. Access them under the names [TreeSet](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/TreeSet.html) and [TreeMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/TreeMap.html). scala> scala.collection.immutable.TreeSet.empty[Int] @@ -170,7 +170,7 @@ Red-black trees are the standard implementation of `SortedSet` in Scala, because ## Immutable BitSets -A [BitSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/BitSet.html) represents a collection of small integers as the bits of a larger integer. For example, the bit set containing 3, 2, and 0 would be represented as the integer 1101 in binary, which is 13 in decimal. +A [BitSet](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/BitSet.html) represents a collection of small integers as the bits of a larger integer. For example, the bit set containing 3, 2, and 0 would be represented as the integer 1101 in binary, which is 13 in decimal. Internally, bit sets use an array of 64-bit `Long`s. The first `Long` in the array is for integers 0 through 63, the second is for 64 through 127, and so on. Thus, bit sets are very compact so long as the largest integer in the set is less than a few hundred or so. @@ -187,7 +187,7 @@ Operations on bit sets are very fast. Testing for inclusion takes constant time. ## List Maps -A [ListMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/ListMap.html) represents a map as a linked list of key-value pairs. In general, operations on a list map might have to iterate through the entire list. Thus, operations on a list map take time linear in the size of the map. In fact there is little usage for list maps in Scala because standard immutable maps are almost always faster. The only possible exception to this is if the map is for some reason constructed in such a way that the first elements in the list are selected much more often than the other elements. +A [ListMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/ListMap.html) represents a map as a linked list of key-value pairs. In general, operations on a list map might have to iterate through the entire list. Thus, operations on a list map take time linear in the size of the map. In fact there is little usage for list maps in Scala because standard immutable maps are almost always faster. The only possible exception to this is if the map is for some reason constructed in such a way that the first elements in the list are selected much more often than the other elements. scala> val map = scala.collection.immutable.ListMap(1->"one", 2->"two") map: scala.collection.immutable.ListMap[Int,java.lang.String] = diff --git a/_overviews/collections/concrete-mutable-collection-classes.md b/_overviews/collections/concrete-mutable-collection-classes.md index f229dc818d..432eb6df9f 100644 --- a/_overviews/collections/concrete-mutable-collection-classes.md +++ b/_overviews/collections/concrete-mutable-collection-classes.md @@ -17,7 +17,7 @@ You've now seen the most commonly used immutable collection classes that Scala p ## Array Buffers -An [ArrayBuffer](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ArrayBuffer.html) buffer holds an array and a size. Most operations on an array buffer have the same speed as for an array, because the operations simply access and modify the underlying array. Additionally, array buffers can have data efficiently added to the end. Appending an item to an array buffer takes amortized constant time. Thus, array buffers are useful for efficiently building up a large collection whenever the new items are always added to the end. +An [ArrayBuffer](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/ArrayBuffer.html) buffer holds an array and a size. Most operations on an array buffer have the same speed as for an array, because the operations simply access and modify the underlying array. Additionally, array buffers can have data efficiently added to the end. Appending an item to an array buffer takes amortized constant time. Thus, array buffers are useful for efficiently building up a large collection whenever the new items are always added to the end. scala> val buf = scala.collection.mutable.ArrayBuffer.empty[Int] buf: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer() @@ -30,7 +30,7 @@ An [ArrayBuffer](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/co ## List Buffers -A [ListBuffer](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ListBuffer.html) is like an array buffer except that it uses a linked list internally instead of an array. If you plan to convert the buffer to a list once it is built up, use a list buffer instead of an array buffer. +A [ListBuffer](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/ListBuffer.html) is like an array buffer except that it uses a linked list internally instead of an array. If you plan to convert the buffer to a list once it is built up, use a list buffer instead of an array buffer. scala> val buf = scala.collection.mutable.ListBuffer.empty[Int] buf: scala.collection.mutable.ListBuffer[Int] = ListBuffer() @@ -43,7 +43,7 @@ A [ListBuffer](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/coll ## StringBuilders -Just like an array buffer is useful for building arrays, and a list buffer is useful for building lists, a [StringBuilder](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/StringBuilder.html) is useful for building strings. String builders are so commonly used that they are already imported into the default namespace. Create them with a simple `new StringBuilder`, like this: +Just like an array buffer is useful for building arrays, and a list buffer is useful for building lists, a [StringBuilder](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/StringBuilder.html) is useful for building strings. String builders are so commonly used that they are already imported into the default namespace. Create them with a simple `new StringBuilder`, like this: scala> val buf = new StringBuilder buf: StringBuilder = @@ -56,15 +56,15 @@ Just like an array buffer is useful for building arrays, and a list buffer is us ## Linked Lists -Linked lists are mutable sequences that consist of nodes which are linked with next pointers. They are supported by class [LinkedList](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/LinkedList.html). In most languages `null` would be picked as the empty linked list. That does not work for Scala collections, because even empty sequences must support all sequence methods. In particular `LinkedList.empty.isEmpty` should return `true` and not throw a `NullPointerException`. Empty linked lists are encoded instead in a special way: Their `next` field points back to the node itself. Like their immutable cousins, linked lists are best traversed sequentially. In addition linked lists make it easy to insert an element or linked list into another linked list. +Linked lists are mutable sequences that consist of nodes which are linked with next pointers. They are supported by class [LinkedList](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/LinkedList.html). In most languages `null` would be picked as the empty linked list. That does not work for Scala collections, because even empty sequences must support all sequence methods. In particular `LinkedList.empty.isEmpty` should return `true` and not throw a `NullPointerException`. Empty linked lists are encoded instead in a special way: Their `next` field points back to the node itself. Like their immutable cousins, linked lists are best traversed sequentially. In addition linked lists make it easy to insert an element or linked list into another linked list. ## Double Linked Lists -Double linked lists are like single linked lists, except that they have besides `next` another mutable field `prev` that points to the element preceding the current node. The main benefit of that additional link is that it makes element removal very fast. Double linked lists are supported by class [DoubleLinkedList](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/DoubleLinkedList.html). +Double linked lists are like single linked lists, except that they have besides `next` another mutable field `prev` that points to the element preceding the current node. The main benefit of that additional link is that it makes element removal very fast. Double linked lists are supported by class [DoubleLinkedList](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/DoubleLinkedList.html). ## Mutable Lists -A [MutableList](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/MutableList.html) consists of a single linked list together with a pointer that refers to the terminal empty node of that list. This makes list append a constant time operation because it avoids having to traverse the list in search for its terminal node. [MutableList](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/MutableList.html) is currently the standard implementation of [mutable.LinearSeq](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/LinearSeq.html) in Scala. +A [MutableList](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/MutableList.html) consists of a single linked list together with a pointer that refers to the terminal empty node of that list. This makes list append a constant time operation because it avoids having to traverse the list in search for its terminal node. [MutableList](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/MutableList.html) is currently the standard implementation of [mutable.LinearSeq](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/LinearSeq.html) in Scala. ## Queues @@ -85,13 +85,13 @@ Scala provides mutable queues in addition to immutable ones. You use a `mQueue` ## Array Sequences -Array sequences are mutable sequences of fixed size which store their elements internally in an `Array[Object]`. They are implemented in Scala by class [ArraySeq](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ArraySeq.html). +Array sequences are mutable sequences of fixed size which store their elements internally in an `Array[Object]`. They are implemented in Scala by class [ArraySeq](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/ArraySeq.html). You would typically use an `ArraySeq` if you want an array for its performance characteristics, but you also want to create generic instances of the sequence where you do not know the type of the elements and you do not have a `ClassTag` to provide it at run-time. These issues are explained in the section on [arrays]({{ site.baseurl }}/overviews/collections/arrays.html). ## Stacks -You saw immutable stacks earlier. There is also a mutable version, supported by class [mutable.Stack](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/Stack.html). It works exactly the same as the immutable version except that modifications happen in place. +You saw immutable stacks earlier. There is also a mutable version, supported by class [mutable.Stack](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/Stack.html). It works exactly the same as the immutable version except that modifications happen in place. scala> val stack = new scala.collection.mutable.Stack[Int] stack: scala.collection.mutable.Stack[Int] = Stack() @@ -114,11 +114,11 @@ You saw immutable stacks earlier. There is also a mutable version, supported by ## Array Stacks -[ArrayStack](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ArrayStack.html) is an alternative implementation of a mutable stack which is backed by an Array that gets re-sized as needed. It provides fast indexing and is generally slightly more efficient for most operations than a normal mutable stack. +[ArrayStack](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/ArrayStack.html) is an alternative implementation of a mutable stack which is backed by an Array that gets re-sized as needed. It provides fast indexing and is generally slightly more efficient for most operations than a normal mutable stack. ## Hash Tables -A hash table stores its elements in an underlying array, placing each item at a position in the array determined by the hash code of that item. Adding an element to a hash table takes only constant time, so long as there isn't already another element in the array that has the same hash code. Hash tables are thus very fast so long as the objects placed in them have a good distribution of hash codes. As a result, the default mutable map and set types in Scala are based on hash tables. You can access them also directly under the names [mutable.HashSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/HashSet.html) and [mutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/HashMap.html). +A hash table stores its elements in an underlying array, placing each item at a position in the array determined by the hash code of that item. Adding an element to a hash table takes only constant time, so long as there isn't already another element in the array that has the same hash code. Hash tables are thus very fast so long as the objects placed in them have a good distribution of hash codes. As a result, the default mutable map and set types in Scala are based on hash tables. You can access them also directly under the names [mutable.HashSet](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/HashSet.html) and [mutable.HashMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/HashMap.html). Hash sets and maps are used just like any other set or map. Here are some simple examples: @@ -137,11 +137,11 @@ Iteration over a hash table is not guaranteed to occur in any particular order. ## Weak Hash Maps -A weak hash map is a special kind of hash map where the garbage collector does not follow links from the map to the keys stored in it. This means that a key and its associated value will disappear from the map if there is no other reference to that key. Weak hash maps are useful for tasks such as caching, where you want to re-use an expensive function's result if the function is called again on the same key. If keys and function results are stored in a regular hash map, the map could grow without bounds, and no key would ever become garbage. Using a weak hash map avoids this problem. As soon as a key object becomes unreachable, it's entry is removed from the weak hashmap. Weak hash maps in Scala are implemented by class [WeakHashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/WeakHashMap.html) as a wrapper of an underlying Java implementation `java.util.WeakHashMap`. +A weak hash map is a special kind of hash map where the garbage collector does not follow links from the map to the keys stored in it. This means that a key and its associated value will disappear from the map if there is no other reference to that key. Weak hash maps are useful for tasks such as caching, where you want to re-use an expensive function's result if the function is called again on the same key. If keys and function results are stored in a regular hash map, the map could grow without bounds, and no key would ever become garbage. Using a weak hash map avoids this problem. As soon as a key object becomes unreachable, it's entry is removed from the weak hashmap. Weak hash maps in Scala are implemented by class [WeakHashMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/WeakHashMap.html) as a wrapper of an underlying Java implementation `java.util.WeakHashMap`. ## Concurrent Maps -A concurrent map can be accessed by several threads at once. In addition to the usual [Map](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Map.html) operations, it provides the following atomic operations: +A concurrent map can be accessed by several threads at once. In addition to the usual [Map](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Map.html) operations, it provides the following atomic operations: ### Operations in class ConcurrentMap @@ -156,7 +156,7 @@ A concurrent map can be accessed by several threads at once. In addition to the ## Mutable Bitsets -A mutable bit of type [mutable.BitSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/BitSet.html) set is just like an immutable one, except that it is modified in place. Mutable bit sets are slightly more efficient at updating than immutable ones, because they don't have to copy around `Long`s that haven't changed. +A mutable bit of type [mutable.BitSet](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/BitSet.html) set is just like an immutable one, except that it is modified in place. Mutable bit sets are slightly more efficient at updating than immutable ones, because they don't have to copy around `Long`s that haven't changed. scala> val bits = scala.collection.mutable.BitSet.empty bits: scala.collection.mutable.BitSet = BitSet() diff --git a/_overviews/collections/conversions-between-java-and-scala-collections.md b/_overviews/collections/conversions-between-java-and-scala-collections.md index c476d4369c..7d1f3d150a 100644 --- a/_overviews/collections/conversions-between-java-and-scala-collections.md +++ b/_overviews/collections/conversions-between-java-and-scala-collections.md @@ -15,7 +15,7 @@ permalink: /overviews/collections/:title.html Like Scala, Java also has a rich collections library. There are many similarities between the two. For instance, both libraries know iterators, iterables, sets, maps, and sequences. But there are also important differences. In particular, the Scala libraries put much more emphasis on immutable collections, and provide many more operations that transform a collection into a new one. -Sometimes you might need to pass from one collection framework to the other. For instance, you might want to access an existing Java collection as if it were a Scala collection. Or you might want to pass one of Scala's collections to a Java method that expects its Java counterpart. It is quite easy to do this, because Scala offers implicit conversions between all the major collection types in the [JavaConverters](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/JavaConverters$.html) object. In particular, you will find bidirectional conversions between the following types. +Sometimes you might need to pass from one collection framework to the other. For instance, you might want to access an existing Java collection as if it were a Scala collection. Or you might want to pass one of Scala's collections to a Java method that expects its Java counterpart. It is quite easy to do this, because Scala offers implicit conversions between all the major collection types in the [JavaConverters](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/JavaConverters$.html) object. In particular, you will find bidirectional conversions between the following types. Iterator <=> java.util.Iterator @@ -27,7 +27,7 @@ Sometimes you might need to pass from one collection framework to the other. For mutable.Map <=> java.util.Map mutable.ConcurrentMap <=> java.util.concurrent.ConcurrentMap -To enable these conversions, simply import them from the [JavaConverters](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/JavaConverters$.html) object: +To enable these conversions, simply import them from the [JavaConverters](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/JavaConverters$.html) object: scala> import collection.JavaConverters._ import collection.JavaConverters._ diff --git a/_overviews/collections/iterators.md b/_overviews/collections/iterators.md index e771513c0c..975824d498 100644 --- a/_overviews/collections/iterators.md +++ b/_overviews/collections/iterators.md @@ -13,7 +13,7 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- -An iterator is not a collection, but rather a way to access the elements of a collection one by one. The two basic operations on an iterator `it` are `next` and `hasNext`. A call to `it.next()` will return the next element of the iterator and advance the state of the iterator. Calling `next` again on the same iterator will then yield the element one beyond the one returned previously. If there are no more elements to return, a call to `next` will throw a `NoSuchElementException`. You can find out whether there are more elements to return using [Iterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html)'s `hasNext` method. +An iterator is not a collection, but rather a way to access the elements of a collection one by one. The two basic operations on an iterator `it` are `next` and `hasNext`. A call to `it.next()` will return the next element of the iterator and advance the state of the iterator. Calling `next` again on the same iterator will then yield the element one beyond the one returned previously. If there are no more elements to return, a call to `next` will throw a `NoSuchElementException`. You can find out whether there are more elements to return using [Iterator](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterator.html)'s `hasNext` method. The most straightforward way to "step through" all the elements returned by an iterator `it` uses a while-loop: @@ -76,7 +76,7 @@ destructively modified by invoking arbitrary methods. This creates the illusion the elements twice, but the effect is achieved through internal buffering. As usual, the underlying iterator `it` cannot be used directly and must be discarded. -In summary, iterators behave like collections _if one never accesses an iterator again after invoking a method on it_. The Scala collection libraries make this explicit with an abstraction [TraversableOnce](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/TraversableOnce.html), which is a common superclass of [Traversable](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Traversable.html) and [Iterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html). As the name implies, `TraversableOnce` objects can be traversed using `foreach` but the state of that object after the traversal is not specified. If the `TraversableOnce` object is in fact an `Iterator`, it will be at its end after the traversal, but if it is a `Traversable`, it will still exist as before. A common use case of `TraversableOnce` is as an argument type for methods that can take either an iterator or a traversable as argument. An example is the appending method `++` in class `Traversable`. It takes a `TraversableOnce` parameter, so you can append elements coming from either an iterator or a traversable collection. +In summary, iterators behave like collections _if one never accesses an iterator again after invoking a method on it_. The Scala collection libraries make this explicit with an abstraction [TraversableOnce](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/TraversableOnce.html), which is a common superclass of [Traversable](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Traversable.html) and [Iterator](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterator.html). As the name implies, `TraversableOnce` objects can be traversed using `foreach` but the state of that object after the traversal is not specified. If the `TraversableOnce` object is in fact an `Iterator`, it will be at its end after the traversal, but if it is a `Traversable`, it will still exist as before. A common use case of `TraversableOnce` is as an argument type for methods that can take either an iterator or a traversable as argument. An example is the appending method `++` in class `Traversable`. It takes a `TraversableOnce` parameter, so you can append elements coming from either an iterator or a traversable collection. All operations on iterators are summarized below. @@ -186,7 +186,7 @@ Sometimes you want an iterator that can "look ahead", so that you can inspect th But looking at this code more closely, it's clear that this is wrong: The code will indeed skip leading empty strings, but it will also advance `it` past the first non-empty string! -The solution to this problem is to use a buffered iterator. Class [BufferedIterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/BufferedIterator.html) is a subclass of [Iterator](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html), which provides one extra method, `head`. Calling `head` on a buffered iterator will return its first element but will not advance the iterator. Using a buffered iterator, skipping empty words can be written as follows. +The solution to this problem is to use a buffered iterator. Class [BufferedIterator](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/BufferedIterator.html) is a subclass of [Iterator](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterator.html), which provides one extra method, `head`. Calling `head` on a buffered iterator will return its first element but will not advance the iterator. Using a buffered iterator, skipping empty words can be written as follows. def skipEmptyWords(it: BufferedIterator[String]) = while (it.head.isEmpty) { it.next() } diff --git a/_overviews/parallel-collections/concrete-parallel-collections.md b/_overviews/parallel-collections/concrete-parallel-collections.md index d171a4968a..3c82e34930 100644 --- a/_overviews/parallel-collections/concrete-parallel-collections.md +++ b/_overviews/parallel-collections/concrete-parallel-collections.md @@ -15,7 +15,7 @@ permalink: /overviews/parallel-collections/:title.html ## Parallel Array -A [ParArray](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/mutable/ParArray.html) +A [ParArray](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/mutable/ParArray.html) sequence holds a linear, contiguous array of elements. This means that the elements can be accessed and updated efficiently by modifying the underlying array. Traversing the @@ -54,7 +54,7 @@ parallel array it was obtained from. ## Parallel Vector -A [ParVector](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/immutable/ParVector.html) +A [ParVector](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/immutable/ParVector.html) is an immutable sequence with a low-constant factor logarithmic access and update time. @@ -76,16 +76,16 @@ combiners will be combined using concatenation and transformer methods will become much more efficient. Parallel vector is a parallel counterpart of the sequential -[Vector](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Vector.html), +[Vector](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Vector.html), so conversion between the two takes constant time. ## Parallel Range -A [ParRange](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/immutable/ParRange.html) +A [ParRange](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/immutable/ParRange.html) is an ordered sequence of elements equally spaced apart. A parallel range is created in a similar way as the sequential -[Range](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Range.html): +[Range](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Range.html): scala> 1 to 3 par res0: scala.collection.parallel.immutable.ParRange = ParRange(1, 2, 3) @@ -105,9 +105,9 @@ another using the `seq` and `par` methods. Parallel hash tables store their elements in an underlying array and place them in the position determined by the hash code of the respective element. Parallel mutable hash sets -([mutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-version}}/scala/collection/parallel/mutable/ParHashSet.html)) +([mutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-212-version}}/scala/collection/parallel/mutable/ParHashSet.html)) and parallel mutable hash maps -([mutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/mutable/ParHashMap.html)) +([mutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/mutable/ParHashMap.html)) are based on hash tables. scala> val phs = scala.collection.parallel.mutable.ParHashSet(1 until 2000: _*) @@ -142,9 +142,9 @@ versa. Parallel hash tries are a parallel counterpart of the immutable hash tries, which are used to represent immutable sets and maps efficiently. They are supported by classes -[immutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/immutable/ParHashSet.html) +[immutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/immutable/ParHashSet.html) and -[immutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-version}}/scala/collection/parallel/immutable/ParHashMap.html). +[immutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-212-version}}/scala/collection/parallel/immutable/ParHashMap.html). scala> val phs = scala.collection.parallel.immutable.ParHashSet(1 until 1000: _*) phs: scala.collection.parallel.immutable.ParHashSet[Int] = ParSet(645, 892, 69, 809, 629, 365, 138, 760, 101, 479,... @@ -165,9 +165,9 @@ by using the `seq` and `par` method in constant time. ## Parallel Concurrent Tries -A [concurrent.TrieMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/concurrent/TrieMap.html) +A [concurrent.TrieMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/concurrent/TrieMap.html) is a concurrent thread-safe map, whereas a -[mutable.ParTrieMap](http://www.scala-lang.org/api/{{ site.scala-version}}/scala/collection/parallel/mutable/ParTrieMap.html) +[mutable.ParTrieMap](http://www.scala-lang.org/api/{{ site.scala-212-version}}/scala/collection/parallel/mutable/ParTrieMap.html) is its parallel counterpart. While most concurrent data structures do not guarantee consistent traversal if the data structure is modified during traversal, Ctries guarantee that updates are only visible in the next iteration. This diff --git a/api/all.md b/api/all.md index 77ecd28618..7c655d88d0 100644 --- a/api/all.md +++ b/api/all.md @@ -6,6 +6,10 @@ includeTOC: true ## Latest releases +* Scala 2.13.0 + * [Library API](https://www.scala-lang.org/api/2.13.0/) + * [Compiler API](https://www.scala-lang.org/api/2.13.0/scala-compiler/scala/) + * [Reflection API](https://www.scala-lang.org/api/2.13.0/scala-reflect/scala/reflect/) * Scala 2.12.8 * [Library API](https://www.scala-lang.org/api/2.12.8/) * [Compiler API](https://www.scala-lang.org/api/2.12.8/scala-compiler/scala/) @@ -26,12 +30,14 @@ includeTOC: true * [Continuations API](https://www.scala-lang.org/files/archive/api/2.11.12/scala-continuations-library/#scala.util.continuations.package) * [Scala 2.10.7](https://www.scala-lang.org/api/2.10.7/) + ## Nightly builds From 7a3d45dd1ab648313aba06fe3b5ec5bbaed74f07 Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Wed, 12 Jun 2019 08:35:59 +0800 Subject: [PATCH 0510/3075] Fix#1368, fill a word for the syntax correctness. --- glossary/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glossary/index.md b/glossary/index.md index 1d4e421eea..472b2ebe3b 100644 --- a/glossary/index.md +++ b/glossary/index.md @@ -267,7 +267,7 @@ A property of functions that are independent of temporal context and have no sid A variable in a running Scala program always _refers_ to some object. Even if that variable is assigned to `null`, it conceptually refers to the `Null` object. At runtime, an object may be implemented by a Java object or a value of a primitive type, but Scala allows programmers to think at a higher level of abstraction about their code as they imagine it running. See also [reference](#reference). * #### refinement type -A type formed by supplying a base type a number of members inside curly braces. The members in the curly braces refine the types that are present in the base type. For example, the type of “animal that eats grass” is `Animal { type SuitableFood = Grass }`. +A type formed by supplying a base type with a number of members inside curly braces. The members in the curly braces refine the types that are present in the base type. For example, the type of “animal that eats grass” is `Animal { type SuitableFood = Grass }`. * #### result An expression in a Scala program yields a _result_. The result of every expression in Scala is an object. From 967cf14521537b389cfa449d17913c13ea74524c Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Wed, 12 Jun 2019 08:44:57 +0800 Subject: [PATCH 0511/3075] Fix#1369, replace quote with italic underbars enclosing to make the term consistent with other terms. --- glossary/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glossary/index.md b/glossary/index.md index 1d4e421eea..6a36a9b3b5 100644 --- a/glossary/index.md +++ b/glossary/index.md @@ -276,7 +276,7 @@ An expression in a Scala program yields a _result_. The result of every expressi A method’s _result type_ is the type of the value that results from calling the method. (In Java, this concept is called the return type.) * #### return -A function in a Scala program `returns` a value. You can call this value the [result](#result) of the function. You can also say the function _results in_ the value. The result of every function in Scala is an object. +A function in a Scala program _returns_ a value. You can call this value the [result](#result) of the function. You can also say the function _results in_ the value. The result of every function in Scala is an object. * #### runtime The Java Virtual Machine, or [JVM](#jvm), that hosts a running Scala program. Runtime encompasses both the virtual machine, as defined by the Java Virtual Machine Specification, and the runtime libraries of the Java API and the standard Scala API. The phrase at run time (with a space between run and time) means when the program is running, and contrasts with compile time. From 7eb53d367d14abab588135ab4da159833e15ad85 Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Wed, 12 Jun 2019 09:20:49 +0800 Subject: [PATCH 0512/3075] Fix issue#1372, add the lost right of parentheses. --- glossary/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glossary/index.md b/glossary/index.md index 1d4e421eea..7cb6cdb063 100644 --- a/glossary/index.md +++ b/glossary/index.md @@ -291,7 +291,7 @@ A file containing top level definitions and statements, which can be run directl The value being matched on in a `match` expression. For example, in “`s match { case _ => }`”, the selector is `s`. * #### self type -A _self type_ of a trait is the assumed type of `this`, the receiver, to be used within the trait. Any concrete class that mixes in the trait must ensure that its type conforms to the trait’s self type. The most common use of self types is for dividing a large class into several traits (as described in Chapter 29 of [Programming in Scala](http://www.artima.com/shop/programming_in_scala). +A _self type_ of a trait is the assumed type of `this`, the receiver, to be used within the trait. Any concrete class that mixes in the trait must ensure that its type conforms to the trait’s self type. The most common use of self types is for dividing a large class into several traits (as described in Chapter 29 of [Programming in Scala](http://www.artima.com/shop/programming_in_scala)). * #### semi-structured data XML data is semi-structured. It is more structured than a flat binary file or text file, but it does not have the full structure of a programming language’s data structures. From 556c843c21b04034e1a3fba578b4e57707b81716 Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Wed, 12 Jun 2019 14:49:35 +0800 Subject: [PATCH 0513/3075] Fix issue#1374, remove bar and space between word 'between'. --- glossary/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glossary/index.md b/glossary/index.md index 1d4e421eea..165accc0db 100644 --- a/glossary/index.md +++ b/glossary/index.md @@ -381,7 +381,7 @@ See [unreachable](#unreachable). The result of any computation or expression in Scala is a _value_, and in Scala, every value is an object. The term value essentially means the image of an object in memory (on the JVM’s heap or stack). * #### value type -A _value type_ is any subclass of `AnyVal`, such as `Int`, `Double`, or `Unit`. This term has meaning at the level of Scala source code. At runtime, instances of value types that correspond to Java primitive types may be implemented in terms of primitive type values or instances of wrapper types, such as `java.lang.Integer`. Over the lifetime of a value type instance, the runtime may transform it back and forth be- tween primitive and wrapper types (_i.e._, to box and unbox it). +A _value type_ is any subclass of `AnyVal`, such as `Int`, `Double`, or `Unit`. This term has meaning at the level of Scala source code. At runtime, instances of value types that correspond to Java primitive types may be implemented in terms of primitive type values or instances of wrapper types, such as `java.lang.Integer`. Over the lifetime of a value type instance, the runtime may transform it back and forth between primitive and wrapper types (_i.e._, to box and unbox it). * #### variable A named entity that refers to an object. A variable is either a `val` or a `var`. Both `val`s and `var`s must be initialized when defined, but only `var`s can be later reassigned to refer to a different object. From 9ff917defe6b08e378fcf973448500b6488c66d3 Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Wed, 12 Jun 2019 15:29:48 +0800 Subject: [PATCH 0514/3075] Fix issue#1376, replace in with of for 'at that point of time' --- glossary/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glossary/index.md b/glossary/index.md index 1d4e421eea..d0b9f78cba 100644 --- a/glossary/index.md +++ b/glossary/index.md @@ -372,7 +372,7 @@ A method’s _type signature_ comprises its name, the number, order, and types o The _uniform access principle_ states that variables and parameterless functions should be accessed using the same syntax. Scala supports this principle by not allowing parentheses to be placed at call sites of parameterless functions. As a result, a parameterless function definition can be changed to a `val`, or _vice versa_, without affecting client code. * #### unreachable -At the Scala level, objects can become _unreachable_, at which point the memory they occupy may be reclaimed by the runtime. Unreachable does not necessarily mean unreferenced. Reference types (instances of `AnyRef`) are implemented as objects that reside on the JVM’s heap. When an instance of a reference type becomes unreachable, it indeed becomes unreferenced, and is available for garbage collection. Value types (instances of `AnyVal`) are implemented as both primitive type values and as instances of Java wrapper types (such as `java.lang.Integer`), which reside on the heap. Value type instances can be boxed (converted from a primitive value to a wrapper object) and unboxed (converted from a wrapper object to a primitive value) throughout the lifetime of the variables that refer to them. If a value type instance currently represented as a wrapper object on the JVM’s heap becomes unreachable, it indeed becomes unreferenced, and is available for garbage collection. But if a value type currently represented as a primitive value becomes unreachable, then it does not become unreferenced, because it does not exist as an object on the JVM’s heap at that point in time. The runtime may reclaim memory occupied by unreachable objects, but if an Int, for example, is implemented at run time by a primitive Java int that occupies some memory in the stack frame of an executing method, then the memory for that object is “reclaimed” when the stack frame is popped as the method completes. Memory for reference types, such as `Strings`, may be reclaimed by the JVM’s garbage collector after they become unreachable. +At the Scala level, objects can become _unreachable_, at which point the memory they occupy may be reclaimed by the runtime. Unreachable does not necessarily mean unreferenced. Reference types (instances of `AnyRef`) are implemented as objects that reside on the JVM’s heap. When an instance of a reference type becomes unreachable, it indeed becomes unreferenced, and is available for garbage collection. Value types (instances of `AnyVal`) are implemented as both primitive type values and as instances of Java wrapper types (such as `java.lang.Integer`), which reside on the heap. Value type instances can be boxed (converted from a primitive value to a wrapper object) and unboxed (converted from a wrapper object to a primitive value) throughout the lifetime of the variables that refer to them. If a value type instance currently represented as a wrapper object on the JVM’s heap becomes unreachable, it indeed becomes unreferenced, and is available for garbage collection. But if a value type currently represented as a primitive value becomes unreachable, then it does not become unreferenced, because it does not exist as an object on the JVM’s heap at that point of time. The runtime may reclaim memory occupied by unreachable objects, but if an Int, for example, is implemented at run time by a primitive Java int that occupies some memory in the stack frame of an executing method, then the memory for that object is “reclaimed” when the stack frame is popped as the method completes. Memory for reference types, such as `Strings`, may be reclaimed by the JVM’s garbage collector after they become unreachable. * #### unreferenced See [unreachable](#unreachable). From c9cfb6e93ee0070f80c61f03eb2d5fd469bc97db Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Wed, 12 Jun 2019 16:19:14 +0800 Subject: [PATCH 0515/3075] This is to add the skeleton of translatable glossary, and the fix of zh-cn for issue#1224. --- _config.yml | 3 + {glossary => _glossary}/index.md | 2 + _layouts/glossary.html | 22 +- _zh-cn/glossary/index.md | 397 +++++++++++++++++++++++++++++++ 4 files changed, 423 insertions(+), 1 deletion(-) rename {glossary => _glossary}/index.md (99%) create mode 100644 _zh-cn/glossary/index.md diff --git a/_config.yml b/_config.yml index e7564efd1a..320c7a9839 100644 --- a/_config.yml +++ b/_config.yml @@ -29,6 +29,9 @@ collections: tutorials: output: true permalink: /:collection/:path.html + glossary: + output: true + permalink: /:collection/:path.html sips: output: true permalink: /:collection/:path.html diff --git a/glossary/index.md b/_glossary/index.md similarity index 99% rename from glossary/index.md rename to _glossary/index.md index 1d4e421eea..95ef0df59f 100644 --- a/glossary/index.md +++ b/_glossary/index.md @@ -1,6 +1,8 @@ --- layout: glossary title: Glossary + +languages: [zh-cn] ---
Glossary from the definitive book on Scala, Programming in Scala.
diff --git a/_layouts/glossary.html b/_layouts/glossary.html index 62b50b0a39..59a14bf8f9 100644 --- a/_layouts/glossary.html +++ b/_layouts/glossary.html @@ -10,7 +10,27 @@
{{content}}
- + {% if page.languages %} + + {% elsif page.language %} + {% assign engPath = page.id | remove_first: "/" | remove_first: page.language | append: '.html' %} + {% assign engPg = site.glossary | first %} + + {% endif %} {% include contributors-list.html %}
diff --git a/_zh-cn/glossary/index.md b/_zh-cn/glossary/index.md new file mode 100644 index 0000000000..bc7aff3156 --- /dev/null +++ b/_zh-cn/glossary/index.md @@ -0,0 +1,397 @@ +--- +layout: glossary +title: Glossary + +language: zh-cn +--- + +
该术语表摘自Scala权威书籍《Programming in Scala
+ +
+ + + +   +
+ +* #### 代数数据类型(algebraic data type) +通过提供若干个带有独立构造器的备选项来定义的类型。它一般通过模式匹配的方式来结构类型,在规约语言和函数式编程语言中常见到这个概念。Scala可通过案例类来模拟代数数据类型。 + +* #### 备选项(alternative) +match表达式的一个分支,形如 “`case` _pattern_ => _expression_”。备选项的别名是 _案例_(_case_)。 + +* #### 注解(annotation) +注解一般出现在源码中,并附加到语法的某个部分。注解对于计算机来说都是可处理的,所以可以用来有效的增加Scala扩展。 + +* #### 匿名类(anonymous class) +匿名类是由Scala编译器根据一种new表达式生成的合成子类,这种new表达式由类名或特质名后面紧跟一对花括号组成。花括号内包含了匿名子类的构造体,可为空,不过一旦跟在new后面名称指向的特质或类包含了抽象成员,则这些抽象成员就必须在其匿名子类的构造体内具化,即在花括号内要实现这些成员。 + +* #### 匿名函数(anonymous function) +[函数字面量](#function-literal)的另一种叫法。 + +* #### 应用(apply) +方法、函数或闭包应用于参数,意思是说通过这些实参来调用方法、函数或闭包。 + +* #### 实参(argument) +在函数调用过程中实参被传给函数的各个参数,其中参数就是指向实参的变量,实参则是调用发生时被传入的对象。另外,应用程序都可以获取被传入单例对象的main方法且类型为`Array[String]`的实参(来自命令行)。 + +* #### 赋值(assign) +可把对象赋值给变量,之后,变量就会指向对象。 + +* #### 辅助构造器(auxiliary constructor) +在类定义体花括号里面定义的所有附加构造器,其形似名为`this`但无结果类型的方法定义。 + +* #### 块(block) +被花括号围起来的一个或多个表达式和声明。求值块的时候,块内所有表达式和声明会被顺序处理,然后会返回最后一个表达式的值作为其自身的值。块通常被用来作为构造体,诸如函数、[for表达式](#for-expression)、`while`循环以及其他任何需要把语句组织到一起的地方,都会用到块。更正式点说,块是一个只其副作用和结果值对外可见的封装构造体。因此,类或对象的花括号是不会形成块的,因其内部定义字段和方法均对外可见。这样的花括号形成的是模板。 + +* #### 绑定变量(bound variable) +表达式的绑定变量是定义和使用都在表达式内部的变量。例如,在函数字面量表达式`(x: Int) => (x, y)`里面,`x`和`y`都被用到了,但只有`x`被绑定了,因为它在表达式中被定义为一个`Int`变量,并且它也是表达式所描述函数的唯一实参。 + +* #### 传名参数(by-name parameter) +参数类型前面带有`=>`的参数,如`(x: => Int)`。传名参数对应的实参求值不在方法被调用前,而是在每次方法通过名称引用到参数的时候。参数若不是传名的,则定是传值的。 + +* #### 传值参数(by-value parameter) +参数类型前面不带`=>`的参数,如`(x: Int)`。传值参数对应的实参是在方法调用前被求值的。传值参数是相对传名参数而言的。 + +* #### 类(class) +通过关键字`class`来定义的类,可抽象可具体,且在实例化时可用类型和值对其进行参数化处理。比如`new Array[String](2)`,被实例化的类是`Array`,产生的值类型为`Array[String]`。带有类型参数的类被称为 _类型构造器_ ,也可说成是类型具有类属性,如:类型`Array[String]`具有的类属性是`Array`。 + +* #### 闭包(closure) +可以捕获自由变量,或者说"关闭"函数创建时可见变量的函数对象。 + +* #### 伴生类(companion class) +和定义在相同源文件中的单例对象共享同一个名称的类,这样的类就叫做那个单例对象的伴生类。 + +* #### 伴生对象(companion object) +和定义在相同源文件中的类共享同一个名称的单例对象。伴生对象和伴生类具备访问彼此私有成员的能力。另外,类不管被用在何处,其伴生对象中定义的任何隐式转换都在其作用域内。 + +* #### 逆变(contravariant) +逆变标注可应用于类或特质的类型参数上,把减号(-)置于类型参数前即可。标注为逆变后类或特质的子类型将逆向(向相反的方向)协变于类型标注的参数。比如,`Function1`的第一个类型参数就是逆变的,所以`Function1[Any, Any]`是`Function1[String, Any]`的子类。 + +* #### 协变(covariant) +协变标注可应用于类或特质的类型参数上,把加号(+)置于类型参数前即可。标注为协变后类或特质的子类型将正向(向相同的方向)协变于类型标注的参数。比如,`List`的类型参数是协变的,所以`List[String]`是`List[Any]`的子类。 + +* #### 柯里化(currying) +把函数写成多个参数列表的方式。例如:`def f(x: Int)(y: Int)`是一个带有两个参数列表的柯里化函数。应用柯里化函数时需传入若干个实参列表,像`f(3)(4)`这样。不过也可以写成柯里化函数的 _部分应用_(partial application),像`f(3)`这样。 + +* #### 声明(declare) +可以通过 _声明_ 抽象的字段、方法或类型来赋给实体一个名称,但是没有具体实现。声明和定义最关键的差异就是定义会为命名实体创建具体实现,而声明则不会。 + +* #### 定义(define) +在Scala程序中若提到 _定义_ 什么东西,就是说给它赋个名称并给出实现。可以定义的东西包括类、特质、单例对象、字段、方法、本地函数、本地变量等。由于提到定义常常会涉及到某种具体实现,故而抽象成员应为声明而非定义。 + +* #### 直接子类(direct subclass) +类是其 _直接子类_ 的直接超类。 + +* #### 直接超类(direct superclass) +从某个类直接衍生出类或特质,或者说在继承层级结构最接近自己的上层的某个类,这样的类就是直接超类。若类`Child`的可选的extends子句中含有类`Parent`,则`Parent`就是`Child`的直接超类。若`Child`的可选extends子句中含有特质,则特质的直接超类也是`Child`的直接超类。若`Child`没有extends子句,则`AnyRef`就是`Child`的直接超类。若类的直接超类带有类型参数,比如`Child extends Parent[String]`,`Child`的直接超类依旧是`Parent`,而不是`Parent[String]`。另一方面,`Parent[String]`应该叫做`Child`的直接超类型。参见[超类型](#supertype)了解更多关于类和类型间的区别。 + +* #### 相等性(equality) +在没有条件限制的情况下使用时,_相等性_ 就是`==`所表达的两个值之间的关系。参见[引用相等性](#reference-equality)。 + +* #### 存在类型(existential type) +存在类型包含未知类型变量的引用。比如:`Array[T] forSome { type T }`是个存在类型,是`T`的数组,而`T`是某个完全未知的类型,关于`T`唯一能够假定的是它是确定存在的。尽管这个假定很虚,但是至少意味着`Array[T] forSome { type T }`确实是个数组,而不是香蕉什么的东西。 + +* #### 表达式(expression) +任何能够得到结果的Scala代码,也可说成表达式求值为某个结果或结果为某个值。 + +* #### 过滤器(filter) +[for表达式](#for-expression)中的`if`及跟在其后的布尔表达式。在`for(i <- 1 to 10; if i % 2 == 0)`中,过滤器为"`if i % 2 == 0`"。`if`右边的值就是[过滤器表达式](#filter-expression),也称为守卫。 + +* #### 过滤器表达式(filter expression) +过滤器表达式就是[for表达式](#for-expression)里面跟在`if`后面的布尔表达式。`for( i <- 1 to 10 ; if i % 2 == 0)`的过滤器表达式为"`i % 2 == 0`"。 + +* #### 头等函数(first-class function) +Scala支持 _头等函数_ ,意味着可以通过函数字面量语法来表达函数。如:`(x: Int) => x + 1`,并且函数可由对象来表达,叫做[函数值](#function-value)。 + +* #### for推解式(for comprehension) +_for推解式_ 是[for表达式](#for-expression)的一种,一般用来创建新的集合。对`for`推解式的每次迭代,[yield](#yield)子句都会定义新集合的一个元素。比如:`for (i <- (0 until 2); j <- (2 until 4)) yield (i, j)`将返回集合`Vector((0,2), (0,3), (1,2), (1,3))`。 + +* #### for表达式(for expression) +_for表达式_ 要么是个[for循环](#for-loop),可以迭代一个或多个集合,要么是个[for推解式](#for-comprehension),可以从一个或多个集合的元素中推解出一个新的集合。`for`表达式建于[生成器](#generator)、[过滤器](#filter)、变量定义和[yield](#yield)子句(针对[for推解式](#for-comprehension))基础之上, + +* #### for循环(for loop) +_for循环_ 是[for表达式](#for-expression)的一种,一般用来循环迭代一个或多个集合。因为`for`循环返回unit,所以经常被用来产生副作用。比如:`for (i <- 0 until 100) println(i)`打印数字0到99。 + +* #### 自由变量(free variable) +一个表达式的 _自由变量_ 指的是在表达式中使用但不定义在其中的变量。例如,在函数字面量表达式`(x: Int) => (x, y)`中,变量`x`和`y`都被用到了,但只有`y`是自由变量,因其未在表达式中定义。 + +* #### 函数(function) +_函数_ 可通过一列实参来[调用](#invoke)然后产生结果。函数一般具有参数列表、函数体和结果类型。作为类、特质或单例对象的函数叫做[方法](#method)。定义在其他函数内部的函数叫做[本地函数](#local-function)。结果类型为`Unit`的函数叫做[过程](#procedure)。源码里面的匿名函数叫做[函数字面量](#function-literal)。运行时,函数字面量被实例化为对象,叫做[函数值](#function-value)。 + +* #### 函数字面量(function literal) +在Scala源码中的无名函数,通过函数字面量语法来特别对待。比如:`(x: Int, y: Int) => x + y`。 + +* #### 函数值(function value) +可以像其他函数一样被调用的函数对象。函数值的类一般是继承了`scala`包中的`FunctionN`(比如`Function0`,`Function1`等)这类特质的其中之一,且在源码中常通过[函数字面量](#function-literal)语法来表示。当函数值的apply方法被调用时就说这个函数值被调用。捕获自由变量的函数值为[闭包](#closure)。 + +* #### 函数式风格(functional style) +_函数式风格_ 编程注重函数和求值结果而非操作发生的顺序。这种风格的特征是可传递函数值给循环方法、不可变数据、方法无副作用,是像Haskell和Erlang等这些语言的主要范式,与[命令式风格](#imperative-style)相对应。 + +* #### 生成器(generator) +生成器在[for表达式](#for-expression)中定义一个命名的val变量并赋予其一系列值。比如:`for(i <- 1 to 10)`的生成器是"`i <- 1 to 10`",`<-`右边的值是[generator表达式](#generator-expression)。 + +* #### 生成器表达式(generator expression) +生成器表达式在[for表达式](#for-expression)中生成一些列值。比如:`for(i <- 1 to 10)`的生成器表达式是"`1 to 10`"。 + +* #### 泛型类(generic class) +带有类型参数的类。例如,因`scala.List`带一类型参数,故其为泛型类。 + +* #### 泛型特质(generic trait) +带有类型参数的特质。例如,因`scala.collection.Set`带一类型参数,故其为泛型特质。 + +* #### 守卫(guard) +参见[过滤器](#filter). + +* #### 助手函数(helper function) +目的是为一个或多个其他邻近函数提供服务的函数。助手函数常实现为本地函数。 + +* #### 助手方法(helper method) +作为类成员的[助手函数](#helper-function)。助手方法常为私有方法。 + +* #### 不可变(immutable) +若对象的值在任何对客户端可见的方式下创建后不会被修改则称对象是 _不可变_ 的。对象既可以是不可变的,也可以是可变的。 + +* #### 命令式风格(imperative style) +_命令式风格_ 编程强调严谨的操作序列以令效用能在正确的顺序发生。这种风格的特征是循环迭代、适当变更数据、方法有副作用,是像C, C++, C#和Java等这些语言的主要范式,与[函数式风格](#functional-style)相对应。 + +* #### 初始化(initialize) +变量在Scala源码中被定义时,必须用对象对其进行初始化。 + +* #### 实例(instance) +_实例_ ,或叫类实例,是个对象,是个仅在运行时存在的概念 + +* #### 实例化(instantiate) +_实例化_ 类是根据类创建一个新对象,是仅在运行时发生的动作。 + +* #### 不变性(invariant) +_不变性_ 用在两个地方。首先在数据结构组织良好的情况下它可以表示某个属性始终为真。比如,若排序二叉树具有右子节点,则其各节点就会在其右子节点前完成排序,这就属于排序二叉树的不变性。其次有时不变性也作为非协变的同义词,如:"类`Array`在类型参数上具备不变性"。 + +* #### 调用(invoke) +在实参上 _调用_ 方法、函数或闭包,意即其方法体会在指定实参上执行。 + +* #### Java虚拟机(JVM) +_JVM_ 是Java虚拟机(#runtime)的缩写,或叫[运行时](#runtime),是运行Scala程序的宿主。 + +* #### 字面量(literal) +`1`,`"One"`,和`(x: Int) => x + 1`是 _字面量_ 的例子,字面量是描述对象的便捷方式,便捷在这种方式正好反映了所创建对象的结构。 + +* #### 本地函数(local function) +_本地函数_ 是块内`def`定义的,作为对比,同为`def`定义的作为类、特质或单例对象的成员则被称作[方法](#method)。 + +* #### 本地变量(local variable) +_本地变量_ 是块内`val`或`var`定义的。尽管函数参数和[本地变量](#local-variable)类似,但并不叫本地变量,而是去掉"本地"直接叫"参数"或"变量"。 + +* #### 成员(member) +_成员_ 是类、特质或单例对象模板中被命名的元素。成员可通过所有者名称,点及其简名访问。例如,定义在类的最顶层字段和方法是这个类的成员。定义在类中的特质是包围它的类的成员。类中通过type关键字定义的类型是这个类的成员。类是其定义所在的包的成员。相比之下,本地变量或本地函数就不是包围他们的块的成员。 + +* #### 消息(message) +Actor是通过给彼此之间发送 _消息_ 来进行通信的。发送消息不会打断接收者正在处理的事情,接收者可一直等到当前活动结束且其不变性被重建之后。 + +* #### 元编程(meta-programming) +元编程程序是指其输入是其自身程序的程序。编译器都是元程序,像`scaladoc`这样的工具也是。要用注解做任何事都需要元编程程序。 + +* #### 方法(method) +_方法_ 就是类、特质或单例对象的成员函数。 + +* #### 混入(mixin) +_混入_ 就是特质用在混入组合时的名称。换言之,在"`trait Hat`"里面,`Hat`仅为特质,而"`new Cat extends AnyRef with Hat`"里面的`Hat`就可叫混入。用作动词时,"混"和"入"("mix in")是两个词。比如,可 _混_ 特质 _入_ 至类或其他特质。 + +* #### 混入组合(mixin composition) +把特质混入类或其他特质的过程。_混入组合_ 与传统的多重继承不同之处在于父级引用的类型不是在特质定义时已知的,而是在每次特质每次混入到类或其他特质时才被重新确定。 + +* #### 修饰符(modifier) +用来以某种方式限定类、特质、字段或方法等的定义的关键字。比如,`private`修饰符表明被定义的类、特质、字段或方法是私有的。 + +* #### 多重定义(multiple definitions) +通过使用类似这样的语法`val v1, v2, v3 = exp`,同一个表达式根据 _多重定义_ 概念可被赋值给多个变量。 + +* #### 非协变(nonvariant) +类或特质的类型参数默认是 _非协变_ 的,故而参数变化并不会子类化相应的类或特质。比如,因类`Array`非协变于其类型参数,故`Array[String]`既非`Array[Any]`之子类,亦非其超类。 + +* #### 操作(operation) +在Scala中,每个 _操作_ 都是一个方法调用。方法也可以 _操作符符号_ 的方式被调用,像在`b + 2`里面符号`+`就是一个 _操作符_。 + +* #### 参数(parameter) +函数可带有零至多个 _参数_,每个参数都有名称和类型。参数与实参之间的区别在于函数调用时实参指向具体的对象,参数则是指向这些传入实参的变量。 + +* #### 无参函数(parameterless function) +不带参数的函数,其定义时没有任何空括号。无参函数可不带括号调用,这种方式符合[统一访问原则](#uniform-access-principle),就是在客户端不改变任何代码的情况下把`def`改成`val`。、 + +* #### 无参方法(parameterless method) +_无参方法_ 就是作为类、特质或单例对象成员的无参函数。 + +* #### 参数化字段(parametric field) +定义为类参数的字段。 + +* #### 偏应用函数(部分应用函数)(partially applied function) +用在表达式中,省掉某些参数的函数。例如:若函数`f`的类型为`Int => Int => Int`,则`f`和`f(1)`就是 _偏应用函数_。 + +* #### 路径依赖类型(path-dependent type) +类似`swiss.cow.Food`的一种类型,`swiss.cow`部分形成一个对象引用的路径。这种类型的含义对于用来访问它的路径是敏感的,比如,`swiss.cow.Food`和`fish.Food`这两个是不同的类型。 + +* #### 模式(pattern) +在`match`表达式的某个备选项中,_模式_ 跟在`case`关键字后,先于 _模式守卫_ 或`=>`符号二者之一。 + +* #### 模式守卫(pattern guard) +在`match`表达式的某个备选项中,_模式守卫_ 可跟在某个[模式](#pattern)后面。比如,"`case x if x % 2 == 0 => x + 1`"中的模式守卫为"`if x % 2 == 0`"。带有模式守卫的备选项(case)仅当其模式匹配了并且模式守卫为真的时候才会被选中。 + +* #### 断言(predicate) +断言是结果类型为`Boolean`的函数。 + +* #### 主构造器(primary constructor) +类的主要构造器,会调用超类构造器,如果有必要,也会初始化字段进行传值,并且会执行类的花括号内定义的的顶层(top-level)代码。字段仅由不传给超类构造器的值参数做初始化,那些类构造体内因未用到而被优化掉的除外。 + +* #### 过程(procedure) +_过程_ 是结果类型为`Unit`的函数,其存在的理由仅为产生副作用。 + +* #### 可重新赋值(reassignable) +变量可以是可重新赋值的,也可以不是可重新赋值的。`var`是可重新赋值的,而`val`则不是。 + +* #### 递归的(recursive) +若函数可调用自身就说它是 _递归的_。若函数调用自身的唯一位置是函数的最后一个表达式,则函数是[尾递归的](#tail-recursive) + +* #### 引用(reference) +_引用_ 是指针的Java抽象,可唯一确定存在JVM堆中的对象。引用类型变量持有对象的引用,因为引用类型(`AnyRef`的实例)是存在JVM堆上的Java对象实现的。相比之下,值类型变量有时会持有一个(装箱类型的)引用,也有时(当对象表示基础类型值的时候)不会。一般说来,Scala变量[指向](#refers)对象。术语"指向"比"持有引用"更加抽象。如果类型为`scala.Int`的变量当前代表Java基础类型`int`的值,则这个变量仍然指向`Int`对象,但并不涉及任何引用。 + +* #### 引用相等性(reference equality) +_引用相等性_ 意思是两个引用指向同一个Java对象。引用相等性仅针对引用类型有意义,是可以通过调用`AnyRef`中的`eq`来确定的(在Java程序中,引用相等性通过在Java[引用类型](#reference-type)上调用`==`来确定)。 + +* #### 引用类型(reference type) +_引用类型_ 是`AnyRef`的子类。在运行时,引用类型的实例常驻JVM堆中。 + +* #### 引用透明(referential transparency) +独立于临时上下文且无副作用的函数属性。对于特定输入,引用透明函数的调用可由其结果替换而不改变程序语义。 + +* #### 指向(refers) +运行的Scala程序中的变量常 _指向_ 某个对象。变量即使被赋为`null`,概念上也是指向`Null`对象。在运行时,对象可由Java对象或基础类型值来实现,不过Scala允许程序员在更高层次抽象代码以他们设想的方式运行。参见[引用](#reference). + +* #### 精化类型(refinement type) +通过提供基础类型及其构造体花括号内若干成员而形成的类型。花括号内的成员精细化了基础类型所体现的类型。比如,"食草动物"(animal that eats grass)的类型为`Animal { type SuitableFood = Grass }`。 +A type formed by supplying a base type a number of members inside curly braces. The members in the curly braces refine the types that are present in the base type. For example, the type of “animal that eats grass” is `Animal { type SuitableFood = Grass }`. + +* #### 结果(result) +Scala程序中的表达式会产生 _结果_。Scala中的每个表达式的结果都是对象。 + +* #### 结果类型(result type) +方法的 _结果类型_ 是调用方法所产生的值的类型。(在Java中,这个概念被称为返回类型) + +* #### 返回(return) +Scala程序中的函数会 _返回_ 值,可把这个值叫做函数的[结果](#result)。也可以说函数 _结果是_ 某个值。Scala中的每个函数结果都是一个对象。 +A function in a Scala program `returns` a value. You can call this value the [result](#result) of the function. You can also say the function _results in_ the value. The result of every function in Scala is an object. + +* #### 运行时(runtime) +正在运行Scala程序的宿主Java虚拟机,或宿主[JVM](#jvm)。运行时这个概念包含了Java虚拟机规范中定义的虚拟机以及Java API和标准Scala API的运行时库。在运行时的这个阶段,意味着程序正在运行中,与编译时是相对的概念。 + +* #### 运行时类型(runtime type) +对象在运行时的类型。相比之下,[静态类型](#static-type)指的是表达式在编译时的类型。多数运行时类型都是无类型参数的裸类,比如,`"Hi"`的运行时类型是`String`,`(x: Int) => x + 1`的运行时类型是`Function1`。运行时类型可通过`isInstanceOf`来检测。 + +* #### 脚本(script) +包含顶层定义和语句,可直接通过`scala`命令来跑而无需显式编译的文件就是脚本,脚本结尾必须是表达式,而不能是定义。 + +* #### 选择器(selector) +`match`表达式中被匹配的值。比如,在"`s match { case _ => }`"中,选择器是`s`。 + +* #### 自身类型(self type) +特质的 _自身类型_ 是特质中用到的接收者`this`的假想类型。任何混入特质的具体类必须要确保其类型符合特质的自身类型。自身类型常被用来把大类分解为若干个特质([Programming in Scala](http://www.artima.com/shop/programming_in_scala)第29章有述)。 + +* #### 半结构化数据(semi-structured data) +XML数据就是半结构化的,因其相比于普通的二进制文件或文本文件更加结构化,而又不像编程语言的数据结构具备完全结构化。 + +* #### 序列化(serialization) +可把对象 _序列化_ 成字节流,以便将其保存至文件或通过网络传输。之后可对字节流进行 _反序列化_ (可发生在不同计算机上)来获取和原始被序列化的对象一样的对象。 + +* #### 遮掩(shadow) +本地变量的重新声明会 _遮掩_ 作用域内相同名称的变量声明。 + +* #### 签名(signature) +_签名_ 是[类型签名](#type-signature)的简写。 + +* #### 单例对象(singleton object) +由object关键字定义的对象。每个单例对象有且仅有一个实例。与某个类共享名称且与这个类定义在同一源文件中的单例对象,叫这个类的[伴随对象](#companion-object),类则叫单列对象的[伴随类](#companion-class)。无伴随类的单例对象叫[独立对象](#standalone-object)。 + +* #### 独立对象(standalone object) +没有[伴生类](#companion-class)的[单例对象](#singleton-object)。 + +* #### 语句(statement) +指的是表达式、定义或包导入等这些可放到Scala源码的模板或块中的东西。 + +* #### 静态类型(static type) +参见[类型](#type)。 + +* #### 结构类型(structural type) +也是一种[精化类型](#refinement-type),只是精化的目标是未在基类型中的成员。比如`{ def close(): Unit }`就是结构类型,因其基类型是`AnyRef`,而`AnyRef`并无名为`close`的成员。 + +* #### 子类(subclass) +一个类是其所有[超类](#superclass)和[超特质](#supertrait)的 _子类_。 + +* #### 子特质(subtrait) +一个特质是其所有[超特质](#supertrait)的 _子特质_。 + +* #### 子类型(subtype) +Scala编译器允许任何类型在需要该类型的地方使用其 _子类型_ 作为替代。对不带类型参数的类和特质来说,子类型的关系会反映子类的关系。比如,若类`Cat`是抽象类`Animal`的子类,且也不带类型参数,则类型`Cat`就是类型`Animal`的子类型。同样,若特质`Apple`是特质`Fruit`的子特质且无类型参数,则类型`Apple`就是类型`Fruit`的子类型。而对于带有类型参数的类和特质来说,协变就起作用了。比如,由于抽象类`List`被声明为在其长类型参数上是协变的(例,`List`被声明为`List[+A]`),`List[Cat]`是`List[Animal]`的子类型,`List[Apple]`是`List[Fruit]`的子类型。尽管这些类型的类都是`List`,但其子类型的关系依旧是存在的。对比来看,因为`Set`未被声明在其类型参数上是协变的(例,`Set`被声明为`Set[A]`,不带加号),所以`Set[Cat]`并不是`Set[Animal]`的子类型。子类型应该正确实现其超类型的契约,以便应用里氏替换原则(Liskov Substitution Principle),不过编译器仅会在类型检查级别核验此属性。 + +* #### 超类(superclass) +一个类的 _超类_ 包括其直接超类,其直接超类的直接超类,等等一直到`Any`。 + +* #### 超特质(supertrait) +类或特质的 _超特质_,如果有的话,就包括所有直接混入类或特质或其任意超类的特质,以及这些特质的所有超特质。 + +* #### 超类型(supertype) +类型是其所有子类型的 _超类型_。 + +* #### 合成类(synthetic class) +合成类是编译器自动生成的而不是程序员手写的。 + +* #### 尾递归(tail recursive) +函数是 _尾递归_ 的,仅当函数调用自身的地方是函数的最后一条操作。 + +* #### 目标类型化(target typing) +_目标类型化_ 是参考所需类型来进行类型推导的一种形式。比如在`nums.filter((x) => x > 0)`中,Scala编译器能推导出`x`的类型是`nums`的元素类型,因为`filter`方法会在`nums`的每个元素上调用函数。 + +* #### 模板(template) +_模板_ 是类、特质或单例对象定义体,它定义了类、特质或对象的类型签名,行为以及初始状态。 + +* #### 特质(trait) +_特质_ 通过`trait`关键字定义,是像抽象类一样不带任何值参数,并且可通过被称为[混入组合](#mixin-composition)的过程"混入到"类或其他特质。当某个特质被混入到其他类或特质,它就被叫做[混入](#mixin)。特质可通过一个或多个类型参数化。用类型来参数化后,特质就形成了类型。比如,`Set`是带有单类型参数的特质,而`Set[Int]`却是一个类型。`Set`也被说成是类型`Set[Int]`的"特质"。 + +* #### 类型(type) +Scala程序中每个变量和表达式都有编译时确定的 _类型_。类型可以在运行时限定变量能指向的值和表达式所能产生的值。如果有必要从对象的[运行时类型](#runtime-type)的角度对变量和表达式的类型进行区分的话,他们也被称为 _静态类型_。换句话说,"类型"这个词本身意味着静态类型。类型与类是区分开的因为带有类型参数的类可以构成许多类型。比如,`List`是类不是类型,`List[T]`则是一个带有自由类型参数的类型,`List[Int]`和`List[String]`也是类型(称为实类型因为他们没有自由类型参数)。类型可以有"[类](#class)"或"[特质](#trait)",比如类型`List[Int]`的类是`List`,类型`Set[String]`的特质是`Set`。、 + +* #### 类型约束(type constraint) +有些[注解](#annotation)是 _类型约束_,意味着他们会对类型能够包含的取值增加额外的限制或约束。比如,`@positive`可以是类型`Int`的类型约束,用来限制32位整型的取值为正的整数。类型约束虽然不会被标准Scala编译器检查,但相应的必须可被额外的工具或编译器插件检查。 + +* #### 类型构造器(type constructor) +带类型参数的类或特质。 + +* #### 类型参数(type parameter) +必须被填入类型的泛型类或泛型方法的参数。比如,类`List`定义为"`class List[T] { . . . `",对象`Predef`的一个成员方法`identity`定义为"`def identity[T](x:T) = x`",二者定义中的`T`就是类型参数。 + +* #### 类型签名(type signature) +方法的 _类型签名_ 包括名称,参数(如果有的话)的数量、顺序和类型,以及结果类型。类、特质或单例对象的类型签名包括名称,所有成员和构造器的类型签名,及其声明的继承和混入关系。 + +* #### 统一访问原则(uniform access principle) +_统一访问原则_ 指的是变量和无参函数应以相同的语法来访问。Scala通过不允许在无参函数的调用点放置括号来支持该原则。这样的话,无参函数定义就可以改成`val`而不影响客户端代码,_反之亦然_。 + +* #### 不可达(unreachable) +在Scala层面,对象可以是 _不可达_ 的,此时其所占据的内存可被运行时回收。不可达并不一定意味着未被引用。引用类型(`AnyRef`的实例)被实现为驻于JVM堆上的对象。当引用类型的实例不可达后,它也确实不被引用了,且可被垃圾回收。值类型(`AnyVal`的实例)可被实现为驻于堆中的基础类型值或Java包装类型实例(如`java.lang.Integer`)。值类型实例可在指向他们的变量的整个生命周期内被装箱(从基础类型值转成包装类型对象)或拆箱(从包装类型对象转成基础类型值)。若表现为JVM堆上的包装类型对象的值类型实例不可达,那就确实不会被引用并且可被垃圾回收。但是若正在表现为基础类型值的值类型不可达,则其仍可被引用,因为此时它并不会以作为对象驻于JVM堆上。运行时可回收不可达对象所占据的内存,但是假如一个Int在运行时被实现为Java基础类型int,在一个运行中的方法的栈帧上占据了一些内存,则这个对象的内存将在方法运行完成且栈帧弹出时才被回收。引用类型的内存,比如`Strings`,可在不可达之后由JVM的垃圾收集器回收。 + +* #### 未引用(unreferenced) +参见[不可达](#unreachable)。 + +* #### 值(value) +Scala中的任何计算或表达式的结果都是一个 _值_,而Scala中的每个值都是一个对象。值这个术语本质上是指对象在内存中(在JVM堆或栈上)的镜像。 + +* #### 值类型(value type) +_值类型_ 是`AnyVal`的任意子类,像`Int`,`Double`或`Unit`。该术语具有Scala源码级别的意味。在运行时,对应于Java基础类型的值类型实例可由基础类型值或包装类型实例来实现,比如`java.lang.Integer`。在值类型实例的整个生命周期内,运行时可将其在基础类型和包装类型间来回转换(如,对其装箱和拆箱)。 + +* #### 变量(variable) +指向对象的命名实体。变量要么是`val`,要么是 `var`,`val`变量和`var`变量在定义时都必须被初始化,但仅`var`变量可被重新赋值来指向不同对象。 + +* #### 型变(variance) +类或特质的类型参数可用 _型变_ 标号来做标记,即[协变](#covariant)(+)或[逆变](#contravariant)(-)。这样的型变标号表明了泛型类或特质的子类化是如何开展的,比如,泛型类`List`在其类型参数上是协变的,因此`List[String]`就是`List[Any]`的子类型。默认情况下,即缺少标号`+`或`-`的类型参数是[非协变](#nonvariant)的。 + +* #### 产生(yield) +表达式可以 _产生_ 结果。`yield`关键字指定了[for推解式](#for-comprehension)的结果。 From cc8106fb900d9b9a60de9c8a72569e44fac85c2a Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Wed, 12 Jun 2019 22:29:31 +0800 Subject: [PATCH 0516/3075] Polish. --- _zh-cn/glossary/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_zh-cn/glossary/index.md b/_zh-cn/glossary/index.md index bc7aff3156..37cedcbd39 100644 --- a/_zh-cn/glossary/index.md +++ b/_zh-cn/glossary/index.md @@ -218,7 +218,7 @@ _混入_ 就是特质用在混入组合时的名称。换言之,在"`trait Hat 函数可带有零至多个 _参数_,每个参数都有名称和类型。参数与实参之间的区别在于函数调用时实参指向具体的对象,参数则是指向这些传入实参的变量。 * #### 无参函数(parameterless function) -不带参数的函数,其定义时没有任何空括号。无参函数可不带括号调用,这种方式符合[统一访问原则](#uniform-access-principle),就是在客户端不改变任何代码的情况下把`def`改成`val`。、 +不带参数的函数,其定义时没有任何空括号。无参函数可不带括号调用,这种方式符合[统一访问原则](#uniform-access-principle),就是在客户端不改变任何代码的情况下把`def`改成`val`。 * #### 无参方法(parameterless method) _无参方法_ 就是作为类、特质或单例对象成员的无参函数。 @@ -358,7 +358,7 @@ _模板_ 是类、特质或单例对象定义体,它定义了类、特质或 _特质_ 通过`trait`关键字定义,是像抽象类一样不带任何值参数,并且可通过被称为[混入组合](#mixin-composition)的过程"混入到"类或其他特质。当某个特质被混入到其他类或特质,它就被叫做[混入](#mixin)。特质可通过一个或多个类型参数化。用类型来参数化后,特质就形成了类型。比如,`Set`是带有单类型参数的特质,而`Set[Int]`却是一个类型。`Set`也被说成是类型`Set[Int]`的"特质"。 * #### 类型(type) -Scala程序中每个变量和表达式都有编译时确定的 _类型_。类型可以在运行时限定变量能指向的值和表达式所能产生的值。如果有必要从对象的[运行时类型](#runtime-type)的角度对变量和表达式的类型进行区分的话,他们也被称为 _静态类型_。换句话说,"类型"这个词本身意味着静态类型。类型与类是区分开的因为带有类型参数的类可以构成许多类型。比如,`List`是类不是类型,`List[T]`则是一个带有自由类型参数的类型,`List[Int]`和`List[String]`也是类型(称为实类型因为他们没有自由类型参数)。类型可以有"[类](#class)"或"[特质](#trait)",比如类型`List[Int]`的类是`List`,类型`Set[String]`的特质是`Set`。、 +Scala程序中每个变量和表达式都有编译时确定的 _类型_。类型可以在运行时限定变量能指向的值和表达式所能产生的值。如果有必要从对象的[运行时类型](#runtime-type)的角度对变量和表达式的类型进行区分的话,他们也被称为 _静态类型_。换句话说,"类型"这个词本身意味着静态类型。类型与类是区分开的因为带有类型参数的类可以构成许多类型。比如,`List`是类不是类型,`List[T]`则是一个带有自由类型参数的类型,`List[Int]`和`List[String]`也是类型(称为实类型因为他们没有自由类型参数)。类型可以有"[类](#class)"或"[特质](#trait)",比如类型`List[Int]`的类是`List`,类型`Set[String]`的特质是`Set`。 * #### 类型约束(type constraint) 有些[注解](#annotation)是 _类型约束_,意味着他们会对类型能够包含的取值增加额外的限制或约束。比如,`@positive`可以是类型`Int`的类型约束,用来限制32位整型的取值为正的整数。类型约束虽然不会被标准Scala编译器检查,但相应的必须可被额外的工具或编译器插件检查。 From 0906818684e9063f423dd2d15c1cd411706d90a0 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Wed, 12 Jun 2019 17:47:26 +0200 Subject: [PATCH 0517/3075] Fix links Fix the errors in CI: - ./_site/es/tour/annotations.html * External link https://www.scala-lang.org/api/current/scala/remote.html failed: 404 No error - ./_site/overviews/collections/trait-iterable.html * External link https://www.scala-lang.org/api/current/scala/collection/GenSetLike.html failed: 404 No error htmlproofer 3.9.1 | Error: HTML-Proofer found 2 failures! Use scala-212-version over "current" for the old(!) collections. --- _es/tour/annotations.md | 1 - _overviews/collections/trait-iterable.md | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/_es/tour/annotations.md b/_es/tour/annotations.md index abcd9654bc..4d42a6f406 100644 --- a/_es/tour/annotations.md +++ b/_es/tour/annotations.md @@ -27,7 +27,6 @@ El significado de las anotaciones _depende de la implementación_. En la platafo | [`scala.deprecated`](https://www.scala-lang.org/api/current/scala/deprecated.html) | [`java.lang.Deprecated`](http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Deprecated.html) | | [`scala.inline`](https://www.scala-lang.org/api/current/scala/inline.html) (desde 2.6.0) | sin equivalente | | [`scala.native`](https://www.scala-lang.org/api/current/scala/native.html) (desde 2.6.0) | [`native`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (palabra clave) | -| [`scala.remote`](https://www.scala-lang.org/api/current/scala/remote.html) | [`java.rmi.Remote`](http://java.sun.com/j2se/1.5.0/docs/api/java/rmi/Remote.html) | | [`scala.throws`](https://www.scala-lang.org/api/current/scala/throws.html) | [`throws`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (palabra clave) | | [`scala.transient`](https://www.scala-lang.org/api/current/scala/transient.html) | [`transient`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (palabra clave) | | [`scala.unchecked`](https://www.scala-lang.org/api/current/scala/unchecked.html) (desde 2.4.0) | sin equivalente | diff --git a/_overviews/collections/trait-iterable.md b/_overviews/collections/trait-iterable.md index ed2938fe6d..e478f3d4d7 100644 --- a/_overviews/collections/trait-iterable.md +++ b/_overviews/collections/trait-iterable.md @@ -62,7 +62,7 @@ Trait `Iterable` also adds some other methods to `Traversable` that can be imple | **Comparison:** | | | `xs sameElements ys` |A test whether `xs` and `ys` contain the same elements in the same order| -In the inheritance hierarchy below Iterable you find three traits: [Seq](https://www.scala-lang.org/api/current/scala/collection/Seq.html), [Set](https://www.scala-lang.org/api/current/scala/collection/Set.html), and [Map](https://www.scala-lang.org/api/current/scala/collection/Map.html). `Seq` and `Map` implement the [PartialFunction](https://www.scala-lang.org/api/current/scala/PartialFunction.html) trait with its `apply` and `isDefinedAt` methods, each implemented differently. `Set` gets its `apply` method from [GenSetLike](https://www.scala-lang.org/api/current/scala/collection/GenSetLike.html). +In the inheritance hierarchy below Iterable you find three traits: [Seq](https://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Seq.html), [Set](https://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Set.html), and [Map](https://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Map.html). `Seq` and `Map` implement the [PartialFunction](https://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/PartialFunction.html) trait with its `apply` and `isDefinedAt` methods, each implemented differently. `Set` gets its `apply` method from [GenSetLike](https://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/GenSetLike.html). For sequences, `apply` is positional indexing, where elements are always numbered from `0`. That is, `Seq(1, 2, 3)(1)` gives `2`. For sets, `apply` is a membership test. For instance, `Set('a', 'b', 'c')('b')` gives `true` whereas `Set()('a')` gives `false`. Finally for maps, `apply` is a selection. For instance, `Map('a' -> 1, 'b' -> 10, 'c' -> 100)('b')` gives `10`. From 494bffd50071cba60d72c51abe3ce9453934c371 Mon Sep 17 00:00:00 2001 From: Alfonso Ruzafa Date: Wed, 12 Jun 2019 18:20:53 +0200 Subject: [PATCH 0518/3075] add visual scala reference to learn page --- learn.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/learn.md b/learn.md index 720a2cb3c2..5a6f817518 100644 --- a/learn.md +++ b/learn.md @@ -52,3 +52,6 @@ There are a handful of websites where you can interactively run Scala code in yo ## ScalaCourses [Independent Courseware](http://getscala.com), online self-study or instructor-led Scala and Play courses for a fee. + +## Visual Scala Reference +[Visual Scala Reference](https://superruzafa.github.com/visual-scala-reference/), a guide to visually learn about Scala concepts and functions. From d3aac4ad5c3eb2fd329cd8b3f053d6ff61b5cf96 Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Thu, 13 Jun 2019 09:03:28 +0800 Subject: [PATCH 0519/3075] Polish base on liufengyun's review. --- _zh-cn/glossary/index.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/_zh-cn/glossary/index.md b/_zh-cn/glossary/index.md index 37cedcbd39..1227db611c 100644 --- a/_zh-cn/glossary/index.md +++ b/_zh-cn/glossary/index.md @@ -80,7 +80,7 @@ match表达式的一个分支,形如 “`case` _pattern_ => _expression_”。 可以通过 _声明_ 抽象的字段、方法或类型来赋给实体一个名称,但是没有具体实现。声明和定义最关键的差异就是定义会为命名实体创建具体实现,而声明则不会。 * #### 定义(define) -在Scala程序中若提到 _定义_ 什么东西,就是说给它赋个名称并给出实现。可以定义的东西包括类、特质、单例对象、字段、方法、本地函数、本地变量等。由于提到定义常常会涉及到某种具体实现,故而抽象成员应为声明而非定义。 +在Scala程序中若提到 _定义_ 什么东西,就是说给它赋个名称并给出实现。可以定义的东西包括类、特质、单例对象、字段、方法、局部函数、局部变量等。由于提到定义常常会涉及到某种具体实现,故而抽象成员应为声明而非定义。 * #### 直接子类(direct subclass) 类是其 _直接子类_ 的直接超类。 @@ -119,7 +119,7 @@ _for循环_ 是[for表达式](#for-expression)的一种,一般用来循环迭 一个表达式的 _自由变量_ 指的是在表达式中使用但不定义在其中的变量。例如,在函数字面量表达式`(x: Int) => (x, y)`中,变量`x`和`y`都被用到了,但只有`y`是自由变量,因其未在表达式中定义。 * #### 函数(function) -_函数_ 可通过一列实参来[调用](#invoke)然后产生结果。函数一般具有参数列表、函数体和结果类型。作为类、特质或单例对象的函数叫做[方法](#method)。定义在其他函数内部的函数叫做[本地函数](#local-function)。结果类型为`Unit`的函数叫做[过程](#procedure)。源码里面的匿名函数叫做[函数字面量](#function-literal)。运行时,函数字面量被实例化为对象,叫做[函数值](#function-value)。 +_函数_ 可通过一列实参来[调用](#invoke)然后产生结果。函数一般具有参数列表、函数体和结果类型。作为类、特质或单例对象的函数叫做[方法](#method)。定义在其他函数内部的函数叫做[局部函数](#local-function)。结果类型为`Unit`的函数叫做[过程](#procedure)。源码里面的匿名函数叫做[函数字面量](#function-literal)。运行时,函数字面量被实例化为对象,叫做[函数值](#function-value)。 * #### 函数字面量(function literal) 在Scala源码中的无名函数,通过函数字面量语法来特别对待。比如:`(x: Int, y: Int) => x + y`。 @@ -146,7 +146,7 @@ _函数式风格_ 编程注重函数和求值结果而非操作发生的顺序 参见[过滤器](#filter). * #### 助手函数(helper function) -目的是为一个或多个其他邻近函数提供服务的函数。助手函数常实现为本地函数。 +目的是为一个或多个其他邻近函数提供服务的函数。助手函数常实现为局部函数。 * #### 助手方法(helper method) 作为类成员的[助手函数](#helper-function)。助手方法常为私有方法。 @@ -178,14 +178,14 @@ _JVM_ 是Java虚拟机(#runtime)的缩写,或叫[运行时](#runtime),是运 * #### 字面量(literal) `1`,`"One"`,和`(x: Int) => x + 1`是 _字面量_ 的例子,字面量是描述对象的便捷方式,便捷在这种方式正好反映了所创建对象的结构。 -* #### 本地函数(local function) -_本地函数_ 是块内`def`定义的,作为对比,同为`def`定义的作为类、特质或单例对象的成员则被称作[方法](#method)。 +* #### 局部函数(local function) +_局部函数_ 是块内`def`定义的,作为对比,同为`def`定义的作为类、特质或单例对象的成员则被称作[方法](#method)。 -* #### 本地变量(local variable) -_本地变量_ 是块内`val`或`var`定义的。尽管函数参数和[本地变量](#local-variable)类似,但并不叫本地变量,而是去掉"本地"直接叫"参数"或"变量"。 +* #### 局部变量(local variable) +_局部变量_ 是块内`val`或`var`定义的。尽管函数参数和[局部变量](#local-variable)类似,但并不叫局部变量,而是去掉"局部"直接叫"参数"或"变量"。 * #### 成员(member) -_成员_ 是类、特质或单例对象模板中被命名的元素。成员可通过所有者名称,点及其简名访问。例如,定义在类的最顶层字段和方法是这个类的成员。定义在类中的特质是包围它的类的成员。类中通过type关键字定义的类型是这个类的成员。类是其定义所在的包的成员。相比之下,本地变量或本地函数就不是包围他们的块的成员。 +_成员_ 是类、特质或单例对象模板中被命名的元素。成员可通过所有者名称,点及其简名访问。例如,定义在类的最顶层字段和方法是这个类的成员。定义在类中的特质是包围它的类的成员。类中通过type关键字定义的类型是这个类的成员。类是其定义所在的包的成员。相比之下,局部变量或局部函数就不是包围他们的块的成员。 * #### 消息(message) Actor是通过给彼此之间发送 _消息_ 来进行通信的。发送消息不会打断接收者正在处理的事情,接收者可一直等到当前活动结束且其不变性被重建之后。 @@ -304,7 +304,7 @@ XML数据就是半结构化的,因其相比于普通的二进制文件或文 可把对象 _序列化_ 成字节流,以便将其保存至文件或通过网络传输。之后可对字节流进行 _反序列化_ (可发生在不同计算机上)来获取和原始被序列化的对象一样的对象。 * #### 遮掩(shadow) -本地变量的重新声明会 _遮掩_ 作用域内相同名称的变量声明。 +局部变量的重新声明会 _遮掩_ 作用域内相同名称的变量声明。 * #### 签名(signature) _签名_ 是[类型签名](#type-signature)的简写。 From 7616f33fe9ef0b7b98b468f09b6d78f558f66e2e Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Thu, 13 Jun 2019 09:07:12 +0800 Subject: [PATCH 0520/3075] Polish base on liufengyun's review 2. --- _zh-cn/glossary/index.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_zh-cn/glossary/index.md b/_zh-cn/glossary/index.md index 1227db611c..79893b5298 100644 --- a/_zh-cn/glossary/index.md +++ b/_zh-cn/glossary/index.md @@ -145,11 +145,11 @@ _函数式风格_ 编程注重函数和求值结果而非操作发生的顺序 * #### 守卫(guard) 参见[过滤器](#filter). -* #### 助手函数(helper function) -目的是为一个或多个其他邻近函数提供服务的函数。助手函数常实现为局部函数。 +* #### 辅助函数(helper function) +目的是为一个或多个其他邻近函数提供服务的函数。辅助函数常实现为局部函数。 -* #### 助手方法(helper method) -作为类成员的[助手函数](#helper-function)。助手方法常为私有方法。 +* #### 辅助方法(helper method) +作为类成员的[辅助函数](#helper-function)。辅助方法常为私有方法。 * #### 不可变(immutable) 若对象的值在任何对客户端可见的方式下创建后不会被修改则称对象是 _不可变_ 的。对象既可以是不可变的,也可以是可变的。 From e37260db541f6971087c212a1e995c09b33ce974 Mon Sep 17 00:00:00 2001 From: abosshard <23498828+abosshard@users.noreply.github.com> Date: Sat, 15 Jun 2019 16:27:16 +0200 Subject: [PATCH 0521/3075] Update concrete-mutable-collection-classes.md As there is no immutable version of Stack in 2.13, I adjusted the description accordingly. --- .../collections-2.13/concrete-mutable-collection-classes.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_overviews/collections-2.13/concrete-mutable-collection-classes.md b/_overviews/collections-2.13/concrete-mutable-collection-classes.md index f2cf39eb41..9ddd1242ef 100644 --- a/_overviews/collections-2.13/concrete-mutable-collection-classes.md +++ b/_overviews/collections-2.13/concrete-mutable-collection-classes.md @@ -81,7 +81,8 @@ Scala provides mutable queues in addition to immutable ones. You use a `mQueue` ## Stacks -You saw immutable stacks earlier. There is also a mutable version, supported by class [mutable.Stack](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/Stack.html). It works exactly the same as the immutable version except that modifications happen in place. +A stack implements a data structure which allows to store and retrieve objects in a last-in-first-out (LIFO) fashion. +It is supported by class [mutable.Stack](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/Stack.html). scala> val stack = new scala.collection.mutable.Stack[Int] stack: scala.collection.mutable.Stack[Int] = Stack() From 82bb519d421f07c512f4e9bd77e551b8bd62a78b Mon Sep 17 00:00:00 2001 From: Jim Van Horn Date: Sat, 15 Jun 2019 22:32:41 -0700 Subject: [PATCH 0522/3075] Update creating-collections-from-scratch.md edit for clarity --- .../collections-2.13/creating-collections-from-scratch.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_overviews/collections-2.13/creating-collections-from-scratch.md b/_overviews/collections-2.13/creating-collections-from-scratch.md index c86dd32db2..7f5a0b4ca2 100644 --- a/_overviews/collections-2.13/creating-collections-from-scratch.md +++ b/_overviews/collections-2.13/creating-collections-from-scratch.md @@ -27,7 +27,7 @@ You have syntax `List(1, 2, 3)` to create a list of three integers and `Map('A' List.apply(1.0, 2.0) -So this is a call to the `apply` method of the companion object of the `List` class. That method takes an arbitrary number of arguments and constructs a list from them. Every collection class in the Scala library has a companion object with such an `apply` method. It does not matter whether the collection class represents a concrete implementation, like `List`, or `LazyList` or `Vector`, do, or whether it is an abstract base class such as `Seq`, `Set` or `Iterable`. In the latter case, calling apply will produce some default implementation of the abstract base class. Examples: +So this is a call to the `apply` method of the companion object of the `List` class. That method takes an arbitrary number of arguments and constructs a list from them. Every collection class in the Scala library has a companion object with such an `apply` method. It does not matter whether the collection class represents a concrete implementation, like `List`, `LazyList` or `Vector`, or whether it is an abstract base class such as `Seq`, `Set` or `Iterable`. In the latter case, calling apply will produce some default implementation of the abstract base class. Examples: scala> List(1, 2, 3) res17: List[Int] = List(1, 2, 3) @@ -59,4 +59,4 @@ The operations provided by collection companion objects are summarized in the fo | `C.range(start, end)` | The collection of integers `start` ... `end-1`. | | `C.range(start, end, step)`| The collection of integers starting with `start` and progressing by `step` increments up to, and excluding, the `end` value. | | `C.iterate(x, n)(f)` | The collection of length `n` with elements `x`, `f(x)`, `f(f(x))`, ... | -| `C.unfold(init)(f)` | A collection that uses a function `f` to compute its next element and state, starting from the `init` state.| \ No newline at end of file +| `C.unfold(init)(f)` | A collection that uses a function `f` to compute its next element and state, starting from the `init` state.| From 07135b1bd8aac30b842fb485d1e7a724bba2aeff Mon Sep 17 00:00:00 2001 From: Jim Van Horn Date: Sat, 15 Jun 2019 23:04:18 -0700 Subject: [PATCH 0523/3075] Update seqs.md Corrected distinctBy example result. -jvh --- _overviews/collections-2.13/seqs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/collections-2.13/seqs.md b/_overviews/collections-2.13/seqs.md index d61f7e4f86..4cd3060b68 100644 --- a/_overviews/collections-2.13/seqs.md +++ b/_overviews/collections-2.13/seqs.md @@ -73,7 +73,7 @@ If a sequence is mutable, it offers in addition a side-effecting `update` method | `xs intersect ys` |The multi-set intersection of sequences `xs` and `ys` that preserves the order of elements in `xs`.| | `xs diff ys` |The multi-set difference of sequences `xs` and `ys` that preserves the order of elements in `xs`.| | `xs.distinct` |A subsequence of `xs` that contains no duplicated element.| -| `xs distinctBy f` |A subsequence of `xs` that contains no duplicated element after applying the transforming function `f`. For instance, `List("foo", "bar", "quux").distinctBy(_.length) == List("foo", "bar")`| +| `xs distinctBy f` |A subsequence of `xs` that contains no duplicated element after applying the transforming function `f`. For instance, `List("foo", "bar", "quux").distinctBy(_.length) == List("foo", "quux")`| Trait [Seq](http://www.scala-lang.org/api/current/scala/collection/Seq.html) has two subtraits [LinearSeq](http://www.scala-lang.org/api/current/scala/collection/LinearSeq.html), and [IndexedSeq](http://www.scala-lang.org/api/current/scala/collection/IndexedSeq.html). These do not add any new operations to the immutable branch, but each offers different performance characteristics: A linear sequence has efficient `head` and `tail` operations, whereas an indexed sequence has efficient `apply`, `length`, and (if mutable) `update` operations. Frequently used linear sequences are `scala.collection.immutable.List` and `scala.collection.immutable.LazyList`. Frequently used indexed sequences are `scala.Array` and `scala.collection.mutable.ArrayBuffer`. The `Vector` class provides an interesting compromise between indexed and linear access. It has both effectively constant time indexing overhead and constant time linear access overhead. Because of this, vectors are a good foundation for mixed access patterns where both indexed and linear accesses are used. You'll learn more on vectors [later](concrete-immutable-collection-classes.html). From 4905400e0fb84f54fc5fb66374251cf923d62dc6 Mon Sep 17 00:00:00 2001 From: Dima Kotobotov Date: Tue, 14 May 2019 00:15:26 +0300 Subject: [PATCH 0524/3075] :sparkles: Russian Collections introduction --- _overviews/collections/introduction.md | 2 +- _ru/overviews/collections/introduction.md | 70 +++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 _ru/overviews/collections/introduction.md diff --git a/_overviews/collections/introduction.md b/_overviews/collections/introduction.md index bf16363308..e026efafaa 100644 --- a/_overviews/collections/introduction.md +++ b/_overviews/collections/introduction.md @@ -9,7 +9,7 @@ overview-name: Collections num: 1 -languages: [ja, zh-cn] +languages: [ja, zh-cn, ru] permalink: /overviews/collections/:title.html --- diff --git a/_ru/overviews/collections/introduction.md b/_ru/overviews/collections/introduction.md new file mode 100644 index 0000000000..4f503f94d6 --- /dev/null +++ b/_ru/overviews/collections/introduction.md @@ -0,0 +1,70 @@ +--- +layout: multipage-overview +title: Введение + +discourse: false + +partof: collections +overview-name: Collections + +num: 1 + +language: ru +--- + +**Martin Odersky и Lex Spoon** + +Популярно мнение, что новые коллекции это самое значимое изменение в Scala версии 2.8. +В Scala и раньше были коллекции (и на самом деле, новая модель +во многом совместима с прежней). Но только начиная с версии 2.8 +появилась единая, общая и всеобъемлющая база для всех типов коллекций. + +Несмотря на то, что улучшения коллекций на первый взгляд едва заметны, они могут привести к существенному изменению в вашем стиле программирования. +Теперь чаще, при работе на высоком уровне, вся коллекция становится базовым строительным блоком вашей программы, а не её отдельные элементы. + +К такому стилю программирования необходимо небольшое привыкание. +К счастью, адаптация облегчается приятными свойствами характерными для новых коллекций Scala. +Они обладают простотой в использовании, лаконичностью, безопасностью и универсальностью. + +**Простота:** Небольшого набора из 20-50 методов достаточно для решения большинства задач. +Нет необходимости использовать запутанные циклы или рекурсии. +Персистентные коллекции и операции без побочных эффектов означают, +что вам не нужно беспокоиться о случайном повреждении существующих коллекций новыми данными. +Больше нет путаницы из-за использования итераторов и одновременного изменения коллекций. + +**Лаконичность:** Одной командой можно достичь, столько же, сколько обычно получают используя несколько вложенных операций с циклами. +Вы можете выразить функциональные операции с помощью простого синтаксиса и с легкостью сочетать операции, создавая ощущение +работы со специализированным под задачу языком. + +**Безопасность:** Требуется определенный опыт, чтоб погрузится в эту специфику. +Статически типизированная и функциональная природа коллекций Scala подразумевает, что подавляющее большинство ошибок, которые вы можете совершить, будут пойманы во время компиляции. +Это потому что: + 1. Коллекции сами по себе очень активно используются, поэтому хорошо протестированы. + 2. Использование операции в коллекциях создает явное описание того, что мы ожидаем для входящих данных и для результата. + 3. Это явное описание для входа и результата подвергается статической проверке типа. В результате подавляющее большинство проблем будет проявляться в виде ошибок типов. +Поэтому запуск программ из нескольких сотен строк, с первого раза, вполне типичная ситуация. + + +**Скорость:** Все операции в коллекциях уже настроены и оптимизированы. В результате, работа коллекций получается очень эффективной. +Можно конечно сделать немного более эффективную настройку структур данных и операций с ними, но при этом, +вероятно, вы получите хуже эффективность в непосредственной реализации и использовании. +Кроме того, коллекции оптимизированы для параллельного исполнения на нескольких ядрах. Параллельные коллекции поддерживают те же операции, что и последовательные, поэтому нет необходимости в изучении новых операций или переписывании кода. +Вы можете превратить последовательную коллекцию в параллельную просто вызвав метод `par`. + +**Универсальность:** Коллекции обеспечивают одинаковые операции на любом типе коллекций, где это имеет смысл. Таким образом, можно достичь многого, имея сравнительно небольшой набор операций. Например строка, в принципе, представляет собой последовательность символов. Следовательно, в коллекциях Scala строки поддерживают все операции которые есть у последовательностей (`Seq`). То же самое относится и к массивам. + +**Пример:** Вот лишь одна строчка кода, демонстрирующая преимущества Scala коллекций. + + val (minors, adults) = people partition (_.age < 18) + +Сразу становится понятно, что делает эта строчка: она разделяет коллекцию людей `people` на несовершеннолетних `minors` и взрослых `adults` в зависимости от возраста `age`. +Поскольку метод `partition` определен в базовом типе коллекции `TraversableLike`, этот код работает для любого типа коллекций, включая массивы. +Полученные в результате коллекции `minors` и `adults` будут иметь тот же тип, что и коллекция `people` . + +Этот код намного лаконичнее, чем несколько циклов, необходимых для того, чтоб провести обработку традиционным методом +(три цикла для массива, т.к. промежуточные результаты должны быть сохранены где-то в другом месте). +Как только вы освоите базовую схему работы с коллекциями, вы оцените на сколько проще и безопаснее написание такого кода, в отличии от более низкоуровневого кода с циклами. +Кроме того, сама операция `partition` работает довольно быстро и будет работать еще быстрее на многоядерных процессорах при использовании параллельных коллекций. (Параллельные коллекции стали частью Scala начиная с версии 2.9.) + +В этом разделе подробно рассматриваются API классов коллекций Scala с пользовательской точки зрения. +Вы также познакомитесь со всеми фундаментальными классами и методами, которые есть у коллекций. From 44032b5473103a5cf21a47552398910667898f0d Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Wed, 19 Jun 2019 07:38:39 +0200 Subject: [PATCH 0525/3075] update spec links and advisements partially addresses scala/bug#11566 --- contribute/bug-reporting-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/bug-reporting-guide.md b/contribute/bug-reporting-guide.md index 71cb5e7ad8..bd2f2c70c4 100644 --- a/contribute/bug-reporting-guide.md +++ b/contribute/bug-reporting-guide.md @@ -44,7 +44,7 @@ If you have a code snippet that is resulting in bytecode which you believe is be 5. If you want to file an improvement in the issue tracker please discuss it first on one of the mailing lists. They offer much bigger audience than issue tracker. The latter is not suitable for long discussions. -* Keep in mind that the behavior you are witnessing could be intended. Good formal resources for verifying whether or not the language behavior is intended is either in the [Scala Improvement Proposal Documents](http://docs.scala-lang.org/sips/sip-list.html) or in the [Scala Language Specification](http://www.scala-lang.org/files/archive/spec/2.12/). If in doubt, you may always ask on the [Community Category](https://contributors.scala-lang.org/c/community) or [Stack Overflow](https://stackoverflow.com/questions/tagged/scala). +* Keep in mind that the behavior you are witnessing could be intended. Good formal resources for verifying whether or not the language behavior is intended is either in the [Scala Improvement Proposal Documents](http://docs.scala-lang.org/sips/sip-list.html) or in the [Scala Language Specification](http://www.scala-lang.org/files/archive/spec/2.13/). If in doubt, you may always ask on the [Community Category](https://contributors.scala-lang.org/c/community) or [Stack Overflow](https://stackoverflow.com/questions/tagged/scala). In general, if you find yourself stuck on any of these steps, asking on [Scala Contributors](https://contributors.scala-lang.org/) can be helpful: From e7b6030befe29b9c56eaf4641397d2513fee2223 Mon Sep 17 00:00:00 2001 From: Jorge Vicente Cantero Date: Fri, 21 Jun 2019 08:06:32 +0200 Subject: [PATCH 0526/3075] Migrate to ci.scala-lang Drone 8 instance --- .drone.yml | 1 - .drone.yml.sig | 1 - 2 files changed, 2 deletions(-) delete mode 100644 .drone.yml.sig diff --git a/.drone.yml b/.drone.yml index d36025ce89..7b74f75e3a 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,6 +1,5 @@ pipeline: build: image: scalacenter/scala-rvm-jvm-coursier:2.0 - pull: true commands: - ./scripts/ci.sh diff --git a/.drone.yml.sig b/.drone.yml.sig deleted file mode 100644 index 8240a38b07..0000000000 --- a/.drone.yml.sig +++ /dev/null @@ -1 +0,0 @@ -eyJhbGciOiJIUzI1NiJ9.cGlwZWxpbmU6CiAgYnVpbGQ6CiAgICBpbWFnZTogamRrLXJ2bS1jb3Vyc2llcjpsYXRlc3QKICAgIHB1bGw6IHRydWUKICAgIGNvbW1hbmRzOgogICAgICAtIHNvdXJjZSB-Ly5wcm9maWxlCiAgICAgIC0gYnVuZGxlIGluc3RhbGwKICAgICAgLSAuL3NjcmlwdHMvcnVuLXR1dC5zaAogICAgICAtIHJtIC1yIHR1dC10bXAKICAgICAgLSBidW5kbGUgZXhlYyBqZWt5bGwgYnVpbGQK.7Rp37FEwRqAo85EdFYZh1PoyU8mxpFdEnpchWaQkHCc From 2c87d8ff773632e9da0b1a760a9ee20c304b3fb6 Mon Sep 17 00:00:00 2001 From: mumutu66 <30490822+mumutu66@users.noreply.github.com> Date: Fri, 21 Jun 2019 14:16:43 +0800 Subject: [PATCH 0527/3075] Update breakOut.md fix the B type error --- _overviews/FAQ/breakout.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_overviews/FAQ/breakout.md b/_overviews/FAQ/breakout.md index 0a39214d55..b5ef234cda 100644 --- a/_overviews/FAQ/breakout.md +++ b/_overviews/FAQ/breakout.md @@ -154,7 +154,7 @@ chain, we find that the types passed to `TraversableLike`, and, thus, used by Going back to the example, the first map is receiving a function of type `((Int, String)) => (Int, Int)` and the second map is receiving a function of -type `((Int, String)) => Int`. I use the double parenthesis to emphasize it is +type `((Int, String)) => String`. I use the double parenthesis to emphasize it is a tuple being received, as that's the type of `A` as we saw. With that information, let's consider the other types. @@ -163,7 +163,7 @@ With that information, let's consider the other types. B = (Int, Int) map (_._2): - B = Int + B = String We can see that the type returned by the first `map` is `Map[Int,Int]`, and the second is `Iterable[String]`. Looking at `map`'s definition, it is easy to see From 9d5a769f68e6e1593943efb3549b1a158936e660 Mon Sep 17 00:00:00 2001 From: Jorge Vicente Cantero Date: Fri, 21 Jun 2019 09:12:43 +0200 Subject: [PATCH 0528/3075] Update CI badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bed6ea16d7..93bf91952e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Scala Documentation # -[![Build Status](https://platform-ci.scala-lang.org/api/badges/scala/docs.scala-lang/status.svg)](https://platform-ci.scala-lang.org/scala/docs.scala-lang) +[![Build Status](https://ci.scala-lang.org/api/badges/scala/docs.scala-lang/status.svg)](https://platform-ci.scala-lang.org/scala/docs.scala-lang) This repository contains the source for the Scala documentation website, as well as the source for "Scala Improvement Process" (SIP) documents. From 7fb22d57689d82e20f7bdac4926bbba719d30448 Mon Sep 17 00:00:00 2001 From: cclaudiu81 Date: Fri, 21 Jun 2019 23:11:20 +0300 Subject: [PATCH 0529/3075] PR changes refactored OO info in the page intro & change small things based on the PR review. --- _tour/higher-order-functions.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/_tour/higher-order-functions.md b/_tour/higher-order-functions.md index d6d1681894..f080bb8350 100644 --- a/_tour/higher-order-functions.md +++ b/_tour/higher-order-functions.md @@ -19,6 +19,8 @@ The terminology can get a bit confusing at this point, and we use the phrase "higher order function" for both methods and functions that take functions as parameters or that return a function. +In a pure Object Oriented world a good practice is to avoid exposing methods parameterized with functions that might leak object's internal state. Leaking internal state might break the invariants of the object itself thus violating encapsulation. + One of the most common examples is the higher-order function `map` which is available for collections in Scala. ```tut @@ -58,10 +60,8 @@ case class WeeklyWeatherForecast(temperatures: Seq[Double]) { def forecastInFahrenheit: Seq[Double] = temperatures.map(convertCtoF) // <-- passing the method convertCtoF } ``` -Here the method `convertCtoF` is passed to `forecastInFahrenheit`. This is possible because the compiler coerces `convertCtoF` to the function `x => convertCtoF(x)` (note: `x` will +Here the method `convertCtoF` is passed to the higher order function `map`. This is possible because the compiler coerces `convertCtoF` to the function `x => convertCtoF(x)` (note: `x` will be a generated name which is guaranteed to be unique within its scope). - -In a pure Object Oriented world a good practice is to avoid exposing methods that are parameterized with functions that might escape the internal state of the objects. Leaking internal state might break the invariants of the object itself. ## Functions that accept functions One reason to use higher-order functions is to reduce redundant code. Let's say you wanted some methods that could raise someone's salaries by various factors. Without creating a higher-order function, @@ -104,6 +104,8 @@ object SalaryRaiser { The new method, `promotion`, takes the salaries plus a function of type `Double => Double` (i.e. a function that takes a Double and returns a Double) and returns the product. +Methods and functions usually express behaviours or data transformations, therefore having functions that compose based on other functions can help building generic mechanisms. Those generic operations defer to lock down the entire operation behaviour giving clients a way to control or further customize parts of the operation itself. + ## Functions that return functions There are certain cases where you want to generate a function. Here's an example From 2555a85e19ab9573529beb01f0b35a2d0d3596fe Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Fri, 21 Jun 2019 09:42:37 +0100 Subject: [PATCH 0530/3075] Fix some more links Pin some translated guides back to Scala 2.12, and drop scala.remote in the Korean docs. --- .../concrete-parallel-collections.md | 16 +++++----- .../concrete-immutable-collection-classes.md | 22 +++++++------- .../concrete-mutable-collection-classes.md | 30 +++++++++---------- _ja/overviews/collections/iterators.md | 6 ++-- _ja/overviews/collections/overview.md | 8 ++--- .../collections/trait-traversable.md | 4 +-- .../concrete-parallel-collections.md | 22 +++++++------- _ko/tour/annotations.md | 1 - _overviews/collections/trait-traversable.md | 2 +- _pl/tour/annotations.md | 1 - _pt-br/tour/annotations.md | 1 - _zh-cn/overviews/collections/overview.md | 4 +-- 12 files changed, 57 insertions(+), 60 deletions(-) diff --git a/_es/overviews/parallel-collections/concrete-parallel-collections.md b/_es/overviews/parallel-collections/concrete-parallel-collections.md index 158c923f6e..3cb5e36a94 100644 --- a/_es/overviews/parallel-collections/concrete-parallel-collections.md +++ b/_es/overviews/parallel-collections/concrete-parallel-collections.md @@ -13,7 +13,7 @@ language: es ## Array Paralelo -Una secuencia [ParArray](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/mutable/ParArray.html) contiene un conjunto de elementos contiguos lineales. Esto significa que los elementos pueden ser accedidos y actualizados (modificados) eficientemente al modificar la estructura subyacente (un array). El iterar sobre sus elementos es también muy eficiente por esta misma razón. Los Arrays Paralelos son como arrays en el sentido de que su tamaño es constante. +Una secuencia [ParArray](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/mutable/ParArray.html) contiene un conjunto de elementos contiguos lineales. Esto significa que los elementos pueden ser accedidos y actualizados (modificados) eficientemente al modificar la estructura subyacente (un array). El iterar sobre sus elementos es también muy eficiente por esta misma razón. Los Arrays Paralelos son como arrays en el sentido de que su tamaño es constante. scala> val pa = scala.collection.parallel.mutable.ParArray.tabulate(1000)(x => 2 * x + 1) pa: scala.collection.parallel.mutable.ParArray[Int] = ParArray(1, 3, 5, 7, 9, 11, 13,... @@ -31,7 +31,7 @@ Al invocar el método `seq`, los arrays paralelos son convertidos al tipo de col ## Vector Paralelo -Un [ParVector](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/immutable/ParVector.html) es una secuencia inmutable con un tiempo de acceso y modificación logarítimico bajo a constante. +Un [ParVector](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/immutable/ParVector.html) es una secuencia inmutable con un tiempo de acceso y modificación logarítimico bajo a constante. scala> val pv = scala.collection.parallel.immutable.ParVector.tabulate(1000)(x => x) pv: scala.collection.parallel.immutable.ParVector[Int] = ParVector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9,... @@ -41,11 +41,11 @@ Un [ParVector](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/coll Los vectores inmutables son representados por árboles, por lo que los splitters dividen pasándose subárboles entre ellos. Los combiners concurrentemente mantienen un vector de elementos y son combinados al copiar dichos elementos de forma "retardada". Es por esta razón que los métodos tranformadores son menos escalables que sus contrapartes en arrays paralelos. Una vez que las operaciones de concatenación de vectores estén disponibles en una versión futura de Scala, los combiners podrán usar dichas características y hacer más eficientes los métodos transformadores. -Un vector paralelo es la contraparte paralela de un [Vector](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Vector.html) secuencial, por lo tanto la conversión entre estas dos estructuras se efectúa en tiempo constante. +Un vector paralelo es la contraparte paralela de un [Vector](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Vector.html) secuencial, por lo tanto la conversión entre estas dos estructuras se efectúa en tiempo constante. ## Rango (Range) Paralelo -Un [ParRange](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/immutable/ParRange.html) es una secuencia ordenada separada por intervalos iguales (ej: 1, 2, 3 o 1, 3, 5, 7). Un rango paralelo es creado de forma similar al [Rango](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Range.html) secuencial: +Un [ParRange](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/immutable/ParRange.html) es una secuencia ordenada separada por intervalos iguales (ej: 1, 2, 3 o 1, 3, 5, 7). Un rango paralelo es creado de forma similar al [Rango](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Range.html) secuencial: scala> 1 to 3 par res0: scala.collection.parallel.immutable.ParRange = ParRange(1, 2, 3) @@ -61,7 +61,7 @@ Tal como los rangos secuenciales no tienen constructores, los rangos paralelos n ## Tablas Hash Paralelas -Las tablas hash paralelas almacenan sus elementos en un array subyacente y los almacenan en una posición determinada por el código hash del elemento respectivo. Las versiones mutables de los hash sets paralelos ([mutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-version}}/scala/collection/parallel/mutable/ParHashSet.html)) y los hash maps paraleos ([mutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/mutable/ParHashMap.html)) están basados en tablas hash. +Las tablas hash paralelas almacenan sus elementos en un array subyacente y los almacenan en una posición determinada por el código hash del elemento respectivo. Las versiones mutables de los hash sets paralelos ([mutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-212-version}}/scala/collection/parallel/mutable/ParHashSet.html)) y los hash maps paraleos ([mutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/mutable/ParHashMap.html)) están basados en tablas hash. scala> val phs = scala.collection.parallel.mutable.ParHashSet(1 until 2000: _*) phs: scala.collection.parallel.mutable.ParHashSet[Int] = ParHashSet(18, 327, 736, 1045, 773, 1082,... @@ -75,9 +75,9 @@ Los "Mapas Hash" (Hash Maps) y los "Conjuntos Hash" (Hash Sets) secuenciales pue ## Hash Tries Paralelos -Los Hash Tries paralelos son la contraparte paralela de los hash tries inmutables, que son usados para representar conjuntos y mapas inmutables de forma eficiente. Las clases involucradas son: [immutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/immutable/ParHashSet.html) +Los Hash Tries paralelos son la contraparte paralela de los hash tries inmutables, que son usados para representar conjuntos y mapas inmutables de forma eficiente. Las clases involucradas son: [immutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/immutable/ParHashSet.html) y -[immutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-version}}/scala/collection/parallel/immutable/ParHashMap.html). +[immutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-212-version}}/scala/collection/parallel/immutable/ParHashMap.html). scala> val phs = scala.collection.parallel.immutable.ParHashSet(1 until 1000: _*) phs: scala.collection.parallel.immutable.ParHashSet[Int] = ParSet(645, 892, 69, 809, 629, 365, 138, 760, 101, 479,... @@ -92,7 +92,7 @@ Los hash tries paralelos pueden ser convertidos hacia y desde hash tries secuenc ## Tries Paralelos Concurrentes -Un [concurrent.TrieMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/concurrent/TrieMap.html) es un mapa thread-safe (seguro ante la utilización de múltiples hilos concurrentes) mientras que [mutable.ParTrieMap](http://www.scala-lang.org/api/{{ site.scala-version}}/scala/collection/parallel/mutable/ParTrieMap.html) es su contraparte paralela. Si bien la mayoría de las estructuras de datos no garantizan una iteración consistente si la estructura es modificada en medio de dicha iteración, los tries concurrentes garantizan que las actualizaciones sean solamente visibles en la próxima iteración. Esto significa que es posible mutar el trie concurrente mientras se está iterando sobre este, como en el siguiente ejemplo, que computa e imprime las raíces cuadradas de los números entre 1 y 99: +Un [concurrent.TrieMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/concurrent/TrieMap.html) es un mapa thread-safe (seguro ante la utilización de múltiples hilos concurrentes) mientras que [mutable.ParTrieMap](http://www.scala-lang.org/api/{{ site.scala-212-version}}/scala/collection/parallel/mutable/ParTrieMap.html) es su contraparte paralela. Si bien la mayoría de las estructuras de datos no garantizan una iteración consistente si la estructura es modificada en medio de dicha iteración, los tries concurrentes garantizan que las actualizaciones sean solamente visibles en la próxima iteración. Esto significa que es posible mutar el trie concurrente mientras se está iterando sobre este, como en el siguiente ejemplo, que computa e imprime las raíces cuadradas de los números entre 1 y 99: scala> val numbers = scala.collection.parallel.mutable.ParTrieMap((1 until 100) zip (1 until 100): _*) map { case (k, v) => (k.toDouble, v.toDouble) } numbers: scala.collection.parallel.mutable.ParTrieMap[Double,Double] = ParTrieMap(0.0 -> 0.0, 42.0 -> 42.0, 70.0 -> 70.0, 2.0 -> 2.0,... diff --git a/_ja/overviews/collections/concrete-immutable-collection-classes.md b/_ja/overviews/collections/concrete-immutable-collection-classes.md index 508ca9a227..77a2a4880a 100644 --- a/_ja/overviews/collections/concrete-immutable-collection-classes.md +++ b/_ja/overviews/collections/concrete-immutable-collection-classes.md @@ -16,7 +16,7 @@ Scala は様々な具象不変コレクションクラス (concrete immutable co ## リスト -リスト ([`List`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/List.html)) は有限の不変列だ。リストは最初の要素とリストの残りの部分に定数時間でアクセスでき、また、新たな要素をリストの先頭に追加する定数時間の cons 演算を持つ。他の多くの演算は線形時間で行われる。 +リスト ([`List`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/List.html)) は有限の不変列だ。リストは最初の要素とリストの残りの部分に定数時間でアクセスでき、また、新たな要素をリストの先頭に追加する定数時間の cons 演算を持つ。他の多くの演算は線形時間で行われる。 リストは Scala プログラミングの働き者であり続けてきたので、あえてここで語るべきことは多くない。Scala 2.8 での大きな変更点は `List` クラスはそのサブクラスである `::` とそのサブオブジェクトである `Nil` とともに、論理的にふさわしい `scala.collection.immutable` パッケージで定義されるようになったことだ。`scala` パッケージには `List`、`Nil`、および `::` へのエイリアスがあるため、ユーザの立場から見ると、リストは今まで通り使うことができる。 @@ -24,7 +24,7 @@ Scala は様々な具象不変コレクションクラス (concrete immutable co ## ストリーム -ストリーム ([`Stream`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Stream.html)) はリストに似ているが、要素は遅延評価される。そのため、ストリームは無限の長さをもつことができる。呼び出された要素のみが計算される。他の点においては、ストリームはリストと同じ性能特性をもつ。 +ストリーム ([`Stream`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Stream.html)) はリストに似ているが、要素は遅延評価される。そのため、ストリームは無限の長さをもつことができる。呼び出された要素のみが計算される。他の点においては、ストリームはリストと同じ性能特性をもつ。 リストは `::` 演算子によって構築されるが、ストリームはそれに似た `#::` 演算子によって構築される。以下は、整数の 1, 2, 3 からなる簡単なストリームの例だ: @@ -52,7 +52,7 @@ Scala は様々な具象不変コレクションクラス (concrete immutable co リストはアルゴリズムが慎重にリストの先頭要素 (`head`) のみを処理する場合、非常に効率的だ。`head` の読み込み、追加、および削除は一定数時間で行われるのに対して、リストの後続の要素に対する読み込みや変更は、その要素の深さに依存した線形時間で実行される。 -ベクトル ([`Vector`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Vector.html)) は、ランダムアクセス時の非効率性を解決するために Scala 2.8 から導入された新しいコレクション型だ。ベクトルはどの要素の読み込みも「事実上」定数時間で行う。リストの `head` の読み込みや配列の要素読み込みに比べると大きい定数だが、定数であることには変りない。この結果、ベクトルを使ったアルゴリズムは列の `head` のみを読み込むことに神経質にならなくていい。任意の場所の要素を読み込んだり、変更したりできるため、コードを書くのに便利だ。 +ベクトル ([`Vector`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Vector.html)) は、ランダムアクセス時の非効率性を解決するために Scala 2.8 から導入された新しいコレクション型だ。ベクトルはどの要素の読み込みも「事実上」定数時間で行う。リストの `head` の読み込みや配列の要素読み込みに比べると大きい定数だが、定数であることには変りない。この結果、ベクトルを使ったアルゴリズムは列の `head` のみを読み込むことに神経質にならなくていい。任意の場所の要素を読み込んだり、変更したりできるため、コードを書くのに便利だ。 ベクトルは、他の列と同じように作成され、変更される。 @@ -79,14 +79,14 @@ Scala は様々な具象不変コレクションクラス (concrete immutable co 最後の行が示すように、`updated` の呼び出しは元のベクトル `vec` には一切影響しない。読み込みと同様に、ベクトルの関数型更新も「事実上定数時間」で実行される。ベクトルの真ん中にある要素を更新するには、その要素を格納するノードと、木構造の根ノードからを初めとする全ての親ノードをコピーすることによって行われる。これは関数型更新は、32以内の要素か部分木を格納する 1 〜 5個の ノードを作成することを意味する。これは、可変配列の in-place での上書きに比べると、ずっと時間のかかる計算であるが、ベクトル全体をコピーするよりはずっと安いものだ。 -ベクトルは高速なランダム読み込みと高速な関数型更新の丁度いいバランスを取れているため、不変添字付き列 ([`immutable.IndexedSeq`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/IndexedSeq.html)) トレイトのデフォルトの実装となっている: +ベクトルは高速なランダム読み込みと高速な関数型更新の丁度いいバランスを取れているため、不変添字付き列 ([`immutable.IndexedSeq`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/IndexedSeq.html)) トレイトのデフォルトの実装となっている: scala> collection.immutable.IndexedSeq(1, 2, 3) res2: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3) ## 不変スタック -後入れ先出し (LIFO: last in first out) の列が必要ならば、スタック ([`Stack`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Stack.html)) がある。 `push` メソッドを使ってスタックに要素をプッシュ、`pop` を使ってポップ、そして`top` を使って削除することなく一番上の要素を読み込むことができる。これらの演算は、全て定数時間で行われる。 +後入れ先出し (LIFO: last in first out) の列が必要ならば、スタック ([`Stack`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Stack.html)) がある。 `push` メソッドを使ってスタックに要素をプッシュ、`pop` を使ってポップ、そして`top` を使って削除することなく一番上の要素を読み込むことができる。これらの演算は、全て定数時間で行われる。 以下はスタックに対して行われる簡単な演算の例だ: @@ -105,7 +105,7 @@ Scala は様々な具象不変コレクションクラス (concrete immutable co ## 不変キュー -キュー ([`Queue`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Queue.html)) はスタックに似ているが、後入れ先出し (LIFO: last in first out) ではなく、先入れ先出し (FIFO: +キュー ([`Queue`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Queue.html)) はスタックに似ているが、後入れ先出し (LIFO: last in first out) ではなく、先入れ先出し (FIFO: first in first out) だ。 以下に空の不変キューの作り方を示す: @@ -134,7 +134,7 @@ first in first out) だ。 ## 範囲 -範囲 ([`Range`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Range.html)) は順序付けされた等間隔の整数の列だ。例えば、「1、2、3」は範囲であり、「5、8、11、14」も範囲だ。Scala で範囲を作成するには、予め定義された `to` メソッドと `by` メソッドを使う。 +範囲 ([`Range`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Range.html)) は順序付けされた等間隔の整数の列だ。例えば、「1、2、3」は範囲であり、「5、8、11、14」も範囲だ。Scala で範囲を作成するには、予め定義された `to` メソッドと `by` メソッドを使う。 scala> 1 to 3 res2: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3) @@ -150,7 +150,7 @@ first in first out) だ。 ## ハッシュトライ -ハッシュトライは不変集合と不変マップを効率的に実装する標準的な方法だ。ハッシュトライは、[`immutable.HashMap`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/HashMap.html) クラスによりサポートされている。データ構造は、全てのノードに 32個の要素か 32個の部分木があるという意味でベクトルに似ている。しかし、キーの選択はハッシュコードにより行われる。たとえば、マップから任意のキーを検索する場合、まずキーのハッシュコードを計算する。その後、最初の部分木を選択するのにハッシュコードの下位 5ビットが使われ、次の 5ビットで次の部分木が選択される、という具合だ。ノード内の全ての要素が、その階層までで選ばれているビット範囲内でお互いと異なるハッシュコードを持った時点で選択は終了する。 +ハッシュトライは不変集合と不変マップを効率的に実装する標準的な方法だ。ハッシュトライは、[`immutable.HashMap`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/HashMap.html) クラスによりサポートされている。データ構造は、全てのノードに 32個の要素か 32個の部分木があるという意味でベクトルに似ている。しかし、キーの選択はハッシュコードにより行われる。たとえば、マップから任意のキーを検索する場合、まずキーのハッシュコードを計算する。その後、最初の部分木を選択するのにハッシュコードの下位 5ビットが使われ、次の 5ビットで次の部分木が選択される、という具合だ。ノード内の全ての要素が、その階層までで選ばれているビット範囲内でお互いと異なるハッシュコードを持った時点で選択は終了する。 ハッシュトライは、サイズ相応の高速な検索と、相応に効率的な関数型加算 `(+)` と減算 `(-)` の調度良いバランスが取れている。そのため、ハッシュトライは Scala の不変マップと不変集合のデフォルトの実装を支えている。実は、Scala は要素が 5個未満の不変集合と不変マップに関して、更なる最適化をしている。1 〜 4個の要素を持つ集合とセットは、要素 (マップの場合は、キー/値のペア) をフィールドとして持つ単一のオブジェクトとして格納する。空の不変集合と、空の不変マップは、ぞれぞれ単一のオブジェクトである。空の不変集合や不変マップは、空であり続けるため、データ構造を複製する必要はない。 @@ -158,7 +158,7 @@ first in first out) だ。 赤黒木は、ノードが「赤」か「黒」に色付けされている平衡二分木の一種だ。他の平衡二分木と同様に演算は木のサイズのログ時間内に確実に完了する。 -Scala は内部で赤黒木を使った不変集合と不変マップの実装を提供する。[`TreeSet`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/TreeSet.html) と [`TreeMap`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/TreeMap.html) クラスがそれだ。 +Scala は内部で赤黒木を使った不変集合と不変マップの実装を提供する。[`TreeSet`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/TreeSet.html) と [`TreeMap`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/TreeMap.html) クラスがそれだ。 scala> scala.collection.immutable.TreeSet.empty[Int] res11: scala.collection.immutable.TreeSet[Int] = TreeSet() @@ -170,7 +170,7 @@ Scala は内部で赤黒木を使った不変集合と不変マップの実装 ## 不変ビット集合 -ビット集合 ([`BitSet`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/BitSet.html)) は大きい整数のビットを小さな整数のコレクションを使って表す。例えば、3, 2, と 0 を格納するビット集合は二進法で整数の 1101、十進法で 13 を表す。 +ビット集合 ([`BitSet`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/BitSet.html)) は大きい整数のビットを小さな整数のコレクションを使って表す。例えば、3, 2, と 0 を格納するビット集合は二進法で整数の 1101、十進法で 13 を表す。 内部では、ビット集合は 64ビットの `Long` の配列を使っている。配列の最初の `Long` は 整数の 0〜63、二番目は 64〜127 という具合だ。そのため、ビット集合は最大値が数百以下の場合は非常にコンパクトだ。 @@ -187,7 +187,7 @@ Scala は内部で赤黒木を使った不変集合と不変マップの実装 ## リストマップ -リストマップ ([`ListMap`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/ListMap.html)) は、キー/値ペアの連結リスト (linked list) により実装されたマップを表す。一般的に、リストマップの演算はリスト全体を総なめする必要がある可能性がある。そのため、リストマップの演算はマップのサイズに対して線形時間をとる。標準の不変マップの方が常に高速なので Scala のリストマップが使われることはほとんど無い。唯一性能の差が出る可能性としては、マップが何らかの理由でリストの最初の要素が他の要素に比べてずっと頻繁に読み込まれるように構築された場合だ。 +リストマップ ([`ListMap`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/ListMap.html)) は、キー/値ペアの連結リスト (linked list) により実装されたマップを表す。一般的に、リストマップの演算はリスト全体を総なめする必要がある可能性がある。そのため、リストマップの演算はマップのサイズに対して線形時間をとる。標準の不変マップの方が常に高速なので Scala のリストマップが使われることはほとんど無い。唯一性能の差が出る可能性としては、マップが何らかの理由でリストの最初の要素が他の要素に比べてずっと頻繁に読み込まれるように構築された場合だ。 scala> val map = scala.collection.immutable.ListMap(1->"one", 2->"two") map: scala.collection.immutable.ListMap[Int,java.lang.String] = diff --git a/_ja/overviews/collections/concrete-mutable-collection-classes.md b/_ja/overviews/collections/concrete-mutable-collection-classes.md index 4889c7a559..8534783b1a 100644 --- a/_ja/overviews/collections/concrete-mutable-collection-classes.md +++ b/_ja/overviews/collections/concrete-mutable-collection-classes.md @@ -16,7 +16,7 @@ Scala が標準ライブラリで提供する不変コレクションで最も ## 配列バッファ -配列バッファ ([`ArrayBuffer`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ArrayBuffer.html)) は、配列とサイズを格納するバッファだ。配列バッファの演算のほとんどは、単に内部の配列にアクセスして変更するだけなので、配列の演算と同じ速さで実行される。また、配列バッファは効率的にデータをバッファの最後に追加できる。配列バッファへの要素の追加はならし定数時間 (amortized constant time) で実行される。よって、配列バッファは要素が常に最後に追加される場合、大きいコレクションを効率的に構築するのに便利だ。 +配列バッファ ([`ArrayBuffer`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/ArrayBuffer.html)) は、配列とサイズを格納するバッファだ。配列バッファの演算のほとんどは、単に内部の配列にアクセスして変更するだけなので、配列の演算と同じ速さで実行される。また、配列バッファは効率的にデータをバッファの最後に追加できる。配列バッファへの要素の追加はならし定数時間 (amortized constant time) で実行される。よって、配列バッファは要素が常に最後に追加される場合、大きいコレクションを効率的に構築するのに便利だ。 scala> val buf = scala.collection.mutable.ArrayBuffer.empty[Int] buf: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer() @@ -29,7 +29,7 @@ Scala が標準ライブラリで提供する不変コレクションで最も ## リストバッファ -リストバッファ ([`ListBuffer`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ListBuffer.html)) は、内部に配列の代わりに連結リストを使うこと以外は配列バッファに似ている。バッファを構築後にリストに変換する予定なら、配列バッファの代わりにリストバッファを使うべきだ。 +リストバッファ ([`ListBuffer`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/ListBuffer.html)) は、内部に配列の代わりに連結リストを使うこと以外は配列バッファに似ている。バッファを構築後にリストに変換する予定なら、配列バッファの代わりにリストバッファを使うべきだ。 scala> val buf = scala.collection.mutable.ListBuffer.empty[Int] buf: scala.collection.mutable.ListBuffer[Int] = ListBuffer() @@ -42,7 +42,7 @@ Scala が標準ライブラリで提供する不変コレクションで最も ## 文字列ビルダ -配列バッファが配列を構築するのに便利で、リストバッファがリストを構築するのに便利なように、文字列ビルダ ([`StringBuilder`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/StringBuilder.html)) は文字列を構築するのに便利なものだ。文字列ビルダはあまりに頻繁に使われるため、デフォルトの名前空間に既にインポートされている。以下のように、単に `new StringBuilder` で文字列ビルダを作成することができる: +配列バッファが配列を構築するのに便利で、リストバッファがリストを構築するのに便利なように、文字列ビルダ ([`StringBuilder`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/StringBuilder.html)) は文字列を構築するのに便利なものだ。文字列ビルダはあまりに頻繁に使われるため、デフォルトの名前空間に既にインポートされている。以下のように、単に `new StringBuilder` で文字列ビルダを作成することができる: scala> val buf = new StringBuilder buf: StringBuilder = @@ -55,19 +55,19 @@ Scala が標準ライブラリで提供する不変コレクションで最も ## 連結リスト -連結リスト ([`LinkedList`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/LinkedList.html)) は、`next` ポインタにより連結されたノードから成る可変列だ。多くの言語では空の連結リストを表すのに `null` が選ばれるが、空の列も全ての列演算をサポートする必要があるため、Scala のコレクションでは `null` は都合が悪い。特に、`LinkedList.empty.isEmpty` は `true` を返すべきで、`NullPointerException` を発生させるべきではない。 代わりに、空の連結リストは `next` フィールドがノード自身を指すという特殊な方法で表現されている。不変リスト同様、連結リストは順列通りに探索するのに適している。また、連結リストは要素や他の連結リストを簡単に挿入できるように実装されている。 +連結リスト ([`LinkedList`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/LinkedList.html)) は、`next` ポインタにより連結されたノードから成る可変列だ。多くの言語では空の連結リストを表すのに `null` が選ばれるが、空の列も全ての列演算をサポートする必要があるため、Scala のコレクションでは `null` は都合が悪い。特に、`LinkedList.empty.isEmpty` は `true` を返すべきで、`NullPointerException` を発生させるべきではない。 代わりに、空の連結リストは `next` フィールドがノード自身を指すという特殊な方法で表現されている。不変リスト同様、連結リストは順列通りに探索するのに適している。また、連結リストは要素や他の連結リストを簡単に挿入できるように実装されている。 ## 双方向リスト -双方向リスト ([`DoubleLinkedList`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/DoubleLinkedList.html)) は、`next` の他に、現ノードの一つ前の要素を指す `prev` +双方向リスト ([`DoubleLinkedList`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/DoubleLinkedList.html)) は、`next` の他に、現ノードの一つ前の要素を指す `prev` というもう一つの可変フィールドがあることを除けば、単方向の連結リストに似ている。リンクが一つ増えたことで要素の削除が非常に高速になる。 ## 可変リスト -可変リスト ([`MutableList`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/MutableList.html)) は単方向連結リストとリスト終端の空ノードを参照するポインタから構成される。これにより、リストの最後への要素の追加が、終端ノードのためにリスト全体を探索しなくてよくなるため、定数時間の演算となる。[`MutableList`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/MutableList.html) は、現在 Scala の [`mutable.LinearSeq`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/LinearSeq.html) トレイトの標準実装だ。 +可変リスト ([`MutableList`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/MutableList.html)) は単方向連結リストとリスト終端の空ノードを参照するポインタから構成される。これにより、リストの最後への要素の追加が、終端ノードのためにリスト全体を探索しなくてよくなるため、定数時間の演算となる。[`MutableList`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/MutableList.html) は、現在 Scala の [`mutable.LinearSeq`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/LinearSeq.html) トレイトの標準実装だ。 ## キュー -Scala は不変キューの他に可変キュー ([`mutable.Queue`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/Queue.html)) も提供する。可変キューは不変のものと同じように使えるが、`enqueue` の代わりに `+=` と `++=` 演算子を使って加算する。また、可変キューの `dequeue` は先頭の要素を削除して、それを返す。次に具体例で説明する: +Scala は不変キューの他に可変キュー ([`mutable.Queue`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/Queue.html)) も提供する。可変キューは不変のものと同じように使えるが、`enqueue` の代わりに `+=` と `++=` 演算子を使って加算する。また、可変キューの `dequeue` は先頭の要素を削除して、それを返す。次に具体例で説明する: scala> val queue = new scala.collection.mutable.Queue[String] queue: scala.collection.mutable.Queue[String] = Queue() @@ -84,13 +84,13 @@ Scala は不変キューの他に可変キュー ([`mutable.Queue`](http://www.s ## 配列シーケンス -配列シーケンス ([`ArraySeq`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ArraySeq.html)) は、内部で要素を `Array[Object]` に格納する固定長の可変列だ。 +配列シーケンス ([`ArraySeq`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/ArraySeq.html)) は、内部で要素を `Array[Object]` に格納する固定長の可変列だ。 -典型的には、配列の性能特性が欲しいが、要素の型が特定できず、実行時に `ClassManifest` も無く、ジェネリックな列を作成したい場合に [`ArraySeq`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ArraySeq.html) を使う。この問題は後ほど[配列の節](arrays.html)で説明する。 +典型的には、配列の性能特性が欲しいが、要素の型が特定できず、実行時に `ClassManifest` も無く、ジェネリックな列を作成したい場合に [`ArraySeq`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/ArraySeq.html) を使う。この問題は後ほど[配列の節](arrays.html)で説明する。 ## スタック -既に不変スタックについては説明した。スタックには、[`mutable.Stack`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/Stack.html) クラスにより実装される可変バージョンもある。変更が上書き処理されるという違いの他は、不変バージョンと全く同じように動作する。 +既に不変スタックについては説明した。スタックには、[`mutable.Stack`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/Stack.html) クラスにより実装される可変バージョンもある。変更が上書き処理されるという違いの他は、不変バージョンと全く同じように動作する。 scala> val stack = new scala.collection.mutable.Stack[Int] stack: scala.collection.mutable.Stack[Int] = Stack() @@ -113,11 +113,11 @@ Scala は不変キューの他に可変キュー ([`mutable.Queue`](http://www.s ## 配列スタック -配列スタック ([`ArrayStack`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/ArrayStack.html) ) は、内部に必要に応じて大きさを変えた `Array` を使った、可変スタックの代替実装だ。配列スタックは、高速な添字読み込みを提供し、他の演算に関しても普通の可変スタックに比べて少し効率的だ。 +配列スタック ([`ArrayStack`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/ArrayStack.html) ) は、内部に必要に応じて大きさを変えた `Array` を使った、可変スタックの代替実装だ。配列スタックは、高速な添字読み込みを提供し、他の演算に関しても普通の可変スタックに比べて少し効率的だ。 ## ハッシュテーブル -ハッシュテーブルは、内部で要素を配列に格納し、要素の位置はハッシュコードにより決められる。ハッシュテーブルへの要素の追加は、既に配列の中に同じハッシュコードを持つ他の要素が無い限り、定数時間で行われる。そのため、ハッシュコードの分布が適度である限り非常に高速だ。結果として、Scala の可変マップと可変集合のデフォルトの実装はハッシュテーブルに基づいており、[`mutable.HashSet`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/HashSet.html) クラスと [`mutable.HashMap`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/HashMap.html) クラスから直接アクセスできる。 +ハッシュテーブルは、内部で要素を配列に格納し、要素の位置はハッシュコードにより決められる。ハッシュテーブルへの要素の追加は、既に配列の中に同じハッシュコードを持つ他の要素が無い限り、定数時間で行われる。そのため、ハッシュコードの分布が適度である限り非常に高速だ。結果として、Scala の可変マップと可変集合のデフォルトの実装はハッシュテーブルに基づいており、[`mutable.HashSet`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/HashSet.html) クラスと [`mutable.HashMap`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/HashMap.html) クラスから直接アクセスできる。 ハッシュ集合とハッシュマップは他の集合やマップと変りなく使うことができる。以下に具体例で説明する: @@ -136,11 +136,11 @@ Scala は不変キューの他に可変キュー ([`mutable.Queue`](http://www.s ## ウィークハッシュマップ -ウィークハッシュマップ([`WeakHashMap`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/WeakHashMap.html)) は、ガーベッジコレクタがマップから「弱キー」への参照を追跡しないという特殊なハッシュマップだ。他にキーを参照するものが無くなると、キーとその関連する値はマップから勝手にいなくなる。ウィークハッシュマップは、キーに対する時間のかかる計算結果を再利用するキャッシュのような用途に向いている。キーとその計算結果が普通のハッシュマップに格納された場合、そのマップは限りなく大きくなり続け、キーはガベージコレクタに永遠に回収されない。ウィークハッシュマップを使うことでこの問題を回避できる。キーオブジェクトが到達不可能になり次第、そのエントリーごとウィークハッシュマップから削除される。Scala のウィークハッシュマップは、Java による実装 `java.util.WeakHashMap` のラッパーである [`WeakHashMap`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/WeakHashMap.html) クラスにより実装されている。 +ウィークハッシュマップ([`WeakHashMap`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/WeakHashMap.html)) は、ガーベッジコレクタがマップから「弱キー」への参照を追跡しないという特殊なハッシュマップだ。他にキーを参照するものが無くなると、キーとその関連する値はマップから勝手にいなくなる。ウィークハッシュマップは、キーに対する時間のかかる計算結果を再利用するキャッシュのような用途に向いている。キーとその計算結果が普通のハッシュマップに格納された場合、そのマップは限りなく大きくなり続け、キーはガベージコレクタに永遠に回収されない。ウィークハッシュマップを使うことでこの問題を回避できる。キーオブジェクトが到達不可能になり次第、そのエントリーごとウィークハッシュマップから削除される。Scala のウィークハッシュマップは、Java による実装 `java.util.WeakHashMap` のラッパーである [`WeakHashMap`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/WeakHashMap.html) クラスにより実装されている。 ## 並行マップ -並行マップ (`ConcurrentMap`) は複数のスレッドから同時にアクセスすることできる。通常の[マップ](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Map.html)の演算の他に、以下のアトミックな演算を提供する: +並行マップ (`ConcurrentMap`) は複数のスレッドから同時にアクセスすることできる。通常の[マップ](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Map.html)の演算の他に、以下のアトミックな演算を提供する: ### ConcurrentMap クラスの演算 ### @@ -156,7 +156,7 @@ Scala は不変キューの他に可変キュー ([`mutable.Queue`](http://www.s ## 可変ビット集合 -可変ビット集合 ([`mutable.BitSet`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/BitSet.html)) は、変更が上書き処理される他は不変のものとほとんど同じだ。可変ビット集合は、変更しなかった `Long` をコピーしなくても済むぶん不変ビット集合に比べて少し効率的だ。 +可変ビット集合 ([`mutable.BitSet`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/BitSet.html)) は、変更が上書き処理される他は不変のものとほとんど同じだ。可変ビット集合は、変更しなかった `Long` をコピーしなくても済むぶん不変ビット集合に比べて少し効率的だ。 scala> val bits = scala.collection.mutable.BitSet.empty bits: scala.collection.mutable.BitSet = BitSet() diff --git a/_ja/overviews/collections/iterators.md b/_ja/overviews/collections/iterators.md index 4c2b700761..7ac3076e79 100644 --- a/_ja/overviews/collections/iterators.md +++ b/_ja/overviews/collections/iterators.md @@ -12,7 +12,7 @@ num: 15 language: ja --- -イテレータ ([`Iterator`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html)) はコレクションではなく、コレクションから要素を1つづつアクセスするための方法だ。イテレータ `it` に対する基本的な演算として `next` と `hasNext` の2つがある。 `it.next()` を呼び出すことで、次の要素が返り、イテレータの内部状態が前進する。よって、同じイテレータに対して `next` を再び呼び出すと、前回返したものの次の要素が得られる。返す要素が無くなると、`next` の呼び出しは `NoSuchElementException` を発生させる。返す要素が残っているかは [`Iterator`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html) の `hasNext` メソッドを使って調べることができる。 +イテレータ ([`Iterator`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterator.html)) はコレクションではなく、コレクションから要素を1つづつアクセスするための方法だ。イテレータ `it` に対する基本的な演算として `next` と `hasNext` の2つがある。 `it.next()` を呼び出すことで、次の要素が返り、イテレータの内部状態が前進する。よって、同じイテレータに対して `next` を再び呼び出すと、前回返したものの次の要素が得られる。返す要素が無くなると、`next` の呼び出しは `NoSuchElementException` を発生させる。返す要素が残っているかは [`Iterator`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterator.html) の `hasNext` メソッドを使って調べることができる。 イテレータ `it` が返す全ての要素を渡り歩くのに最も率直な方法は while ループを使うことだ: @@ -64,7 +64,7 @@ language: ja への呼び出しはイテレータ `it` と全く同じ要素を返すイテレータを**2つ**返す。この2つのイテレータは独立して作動するため、片方を前進しても他方は影響を受けない。一方、元のイテレータ `it` は `duplicate` により終端まで前進したため、使いものにならない。 要約すると、イテレータは**メソッドを呼び出した後、絶対にアクセスしなければ**コレクションのように振る舞う。Scala -コレクションライブラリは、[`Traversable`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Traversable.html) と [`Iterator`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html) に共通の親クラスである [`TraversableOnce`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/TraversableOnce.html) を提供することで、明示的にこれを示す。名前が示す通り、 `TraversableOnce` は `foreach` を用いて一度だけ探索することができるが、探索後のそのオブジェクトの状態は指定されていない。`TraversableOnce` オブジェクトが `Iterator` ならば、探索後はその終端にあるし、もし `Traversable` ならば、そのオブジェクトは今まで通り存在する。 `TraversableOnce` のよく使われる事例としては、イテレータか `Traversable` を受け取ることができるメソッドの引数の型だ。その例として、 `Traversable` クラスの追加メソッド `++` がある。`TraversableOnce` パラメータを受け取るため、イテレータか `Traversable` なコレクションの要素を追加することができる。 +コレクションライブラリは、[`Traversable`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Traversable.html) と [`Iterator`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterator.html) に共通の親クラスである [`TraversableOnce`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/TraversableOnce.html) を提供することで、明示的にこれを示す。名前が示す通り、 `TraversableOnce` は `foreach` を用いて一度だけ探索することができるが、探索後のそのオブジェクトの状態は指定されていない。`TraversableOnce` オブジェクトが `Iterator` ならば、探索後はその終端にあるし、もし `Traversable` ならば、そのオブジェクトは今まで通り存在する。 `TraversableOnce` のよく使われる事例としては、イテレータか `Traversable` を受け取ることができるメソッドの引数の型だ。その例として、 `Traversable` クラスの追加メソッド `++` がある。`TraversableOnce` パラメータを受け取るため、イテレータか `Traversable` なコレクションの要素を追加することができる。 イテレータの全演算は次の表にまとめられている。 @@ -158,7 +158,7 @@ language: ja しかし、このコードを慎重に見ると間違っていることが分かるはずだ。コードは確かに先頭の空白文字列の続きを読み飛ばすが、`it` は最初の非空白文字列も追い越してしまっているのだ。 -この問題はバッファ付きイテレータを使うことで解決できる。[`BufferedIterator`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/BufferedIterator.html) トレイトは、`head` というメソッドを追加で提供する [`Iterator`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html) の子トレイトだ。バッファ付きイテレータに対して `head` を呼び出すことで、イテレータを前進させずに最初の要素を返すことができる。バッファ付きイテレータを使うと、空白文字列を読み飛ばすのは以下のように書ける。 +この問題はバッファ付きイテレータを使うことで解決できる。[`BufferedIterator`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/BufferedIterator.html) トレイトは、`head` というメソッドを追加で提供する [`Iterator`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterator.html) の子トレイトだ。バッファ付きイテレータに対して `head` を呼び出すことで、イテレータを前進させずに最初の要素を返すことができる。バッファ付きイテレータを使うと、空白文字列を読み飛ばすのは以下のように書ける。 def skipEmptyWords(it: BufferedIterator[String]) = while (it.head.isEmpty) { it.next() } diff --git a/_ja/overviews/collections/overview.md b/_ja/overviews/collections/overview.md index 82a26ba556..83b514eb30 100644 --- a/_ja/overviews/collections/overview.md +++ b/_ja/overviews/collections/overview.md @@ -22,8 +22,8 @@ Scala のコレクションは、体系的に可変および不変コレクシ `scala.collection.mutable` パッケージのコレクションは、コレクションを上書き変更する演算がある。 だから可変コレクションを扱うということは、どのコードが、何時どのコレクションを変更したのかということを理解する必要があることを意味する。 -`scala.collection` パッケージのコレクションは、可変か不変かのどちらでもありうる。例えば [`collection.IndexedSeq[T]`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/IndexedSeq.html) -は、[`collection.immutable.IndexedSeq[T]`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/IndexedSeq.html) と [`collection.mutable.IndexedSeq[T]`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/IndexedSeq.html) 両方の親クラスだ。一般的に、`scala.collection`パッケージの基底コレクションは不変コレクションと同じインターフェイスを定義し、`scala.collection.mutable` パッケージ内の可変コレクションは、副作用を伴う変更演算を不変インターフェイスに加える。 +`scala.collection` パッケージのコレクションは、可変か不変かのどちらでもありうる。例えば [`collection.IndexedSeq[T]`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/IndexedSeq.html) +は、[`collection.immutable.IndexedSeq[T]`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/IndexedSeq.html) と [`collection.mutable.IndexedSeq[T]`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/IndexedSeq.html) 両方の親クラスだ。一般的に、`scala.collection`パッケージの基底コレクションは不変コレクションと同じインターフェイスを定義し、`scala.collection.mutable` パッケージ内の可変コレクションは、副作用を伴う変更演算を不変インターフェイスに加える。 基底コレクションと不変コレクションの違いは、不変なコレクションのクライアントは、他の誰もコレクションを変更しないという保証があるのに対し、基底コレクションのクライアントは自分ではコレクションを変更しなかったという約束しかできない。たとえ静的な型がコレクションを変更するような演算を提供していなくても、実行時の型は他のクライアントが手を加えることができる可変コレクションである可能性がある。 @@ -40,7 +40,7 @@ Scala のコレクションは、体系的に可変および不変コレクシ このパッケージには、コレクションを実装するための基本的なパーツが含まれている。 コレクションクラスがいくつかの演算を `generic` 内のクラスに委譲することはよくあるが、 フレームワークのユーザーが `generic` 内のクラスが必要になることは普通はありえない。 -利便性と後方互換性のために、いくつかの重要な型は `scala` パッケージ内に別名を定義してあるため、インポート無しで単純な名前でコレクションを使うことができる。[`List`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/List.html) 型が良い例で、以下の名前でもアクセスすることができる +利便性と後方互換性のために、いくつかの重要な型は `scala` パッケージ内に別名を定義してあるため、インポート無しで単純な名前でコレクションを使うことができる。[`List`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/List.html) 型が良い例で、以下の名前でもアクセスすることができる scala.collection.immutable.List // 定義元 scala.List // scala パッケージのエイリアス経由 @@ -48,7 +48,7 @@ Scala のコレクションは、体系的に可変および不変コレクシ // 常に自動的にインポートされるため エイリアスされているその他の型は次のとおり: -[`Traversable`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Traversable.html)、[`Iterable`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterable.html)、[`Seq`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Seq.html)、[`IndexedSeq`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/IndexedSeq.html)、[`Iterator`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html)、[`Stream`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Stream.html)、[`Vector`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Vector.html)、[`StringBuilder`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/mutable/StringBuilder.html)、[`Range`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Range.html)。 +[`Traversable`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Traversable.html)、[`Iterable`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterable.html)、[`Seq`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Seq.html)、[`IndexedSeq`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/IndexedSeq.html)、[`Iterator`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterator.html)、[`Stream`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Stream.html)、[`Vector`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Vector.html)、[`StringBuilder`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/StringBuilder.html)、[`Range`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Range.html)。 次の図は `scala.collection` パッケージ内の全てのコレクションを示す。 これらはすべて、高レベルの抽象クラスやトレイトで一般に可変と不変の両方の実装を持っている。 diff --git a/_ja/overviews/collections/trait-traversable.md b/_ja/overviews/collections/trait-traversable.md index eed29ac4de..52c14efb64 100644 --- a/_ja/overviews/collections/trait-traversable.md +++ b/_ja/overviews/collections/trait-traversable.md @@ -12,7 +12,7 @@ num: 3 language: ja --- -走査可能 ([`Traversable`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Traversable.html))トレイトはコレクション階層の最上位に位置する。訳注: 木構造などでノードを一つづつ走査することを traverse と言う。また、-able で終わるトレイトは名詞としても使われるため、「走査可能なもの」という意味だ。 `Traversable` の抽象的な演算は `foreach` のみだ: +走査可能 ([`Traversable`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Traversable.html))トレイトはコレクション階層の最上位に位置する。訳注: 木構造などでノードを一つづつ走査することを traverse と言う。また、-able で終わるトレイトは名詞としても使われるため、「走査可能なもの」という意味だ。 `Traversable` の抽象的な演算は `foreach` のみだ: def foreach[U](f: Elem => U) @@ -52,7 +52,7 @@ language: ja | **抽象メソッド:** | | | `xs foreach f` |`xs` 内の全ての要素に対して関数 `f` を実行する。 | | **加算:** | | -| `xs ++ ys` |`xs` と `ys` の両方の要素から成るコレクション。 `ys` は [`TraversableOnce`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/TraversableOnce.html) なコレクション、つまり [`Traversable`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Traversable.html) または [`Iterator`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html) だ。| +| `xs ++ ys` |`xs` と `ys` の両方の要素から成るコレクション。 `ys` は [`TraversableOnce`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/TraversableOnce.html) なコレクション、つまり [`Traversable`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Traversable.html) または [`Iterator`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterator.html) だ。| | **map 演算:** | | | `xs map f` |`xs` 内の全ての要素に関数 `f` を適用することによって得られるコレクション。| | `xs flatMap f` |`xs` 内の全ての要素に対してコレクション値を返す関数 `f` を適用し、その結果を連結したコレクション。| diff --git a/_ja/overviews/parallel-collections/concrete-parallel-collections.md b/_ja/overviews/parallel-collections/concrete-parallel-collections.md index 1681cfa468..4951280848 100644 --- a/_ja/overviews/parallel-collections/concrete-parallel-collections.md +++ b/_ja/overviews/parallel-collections/concrete-parallel-collections.md @@ -13,7 +13,7 @@ language: ja ## 並列配列 -並列配列 ([`ParArray`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/mutable/ParArray.html)) は、線形で連続的な要素の配列を保持する列だ。 +並列配列 ([`ParArray`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/mutable/ParArray.html)) は、線形で連続的な要素の配列を保持する列だ。 そのため、内部の配列を変更することで効率的な要素の読み込みや更新ができるようになる。 また、要素の走査も非常に効率的だ。 並列配列は、サイズが一定であるという意味で配列と似ている。 @@ -38,7 +38,7 @@ language: ja ## 並列ベクトル -並列ベクトル ([`ParVector`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/immutable/ParVector.html)) +並列ベクトル ([`ParVector`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/immutable/ParVector.html)) は、低い定数係数の対数時間で読み込みと書き込みを行う不変列だ。 scala> val pv = scala.collection.parallel.immutable.ParVector.tabulate(1000)(x => x) @@ -52,13 +52,13 @@ language: ja このため、変換メソッドは並列配列のそれに比べてスケーラビリティが低い。 ベクトルの連結が将来の Scala リリースで提供されるようになれば、コンバイナは連結を用いて合成できるようになり、変換メソッドはより効率的になる。 -並列ベクトルは、順次[ベクトル](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Vector.html)の並列版で、定数時間で一方から他方へと変換できる。 +並列ベクトルは、順次[ベクトル](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Vector.html)の並列版で、定数時間で一方から他方へと変換できる。 ## 並列範囲 -並列範囲 ([`ParRange`](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/immutable/ParRange.html)) +並列範囲 ([`ParRange`](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/immutable/ParRange.html)) は、順序付けされた等間隔の要素の列だ。 -並列範囲は、逐次版の [Range](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Range.html) と同様に作成される: +並列範囲は、逐次版の [Range](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Range.html) と同様に作成される: scala> 1 to 3 par res0: scala.collection.parallel.immutable.ParRange = ParRange(1, 2, 3) @@ -74,8 +74,8 @@ language: ja 並列ハッシュテーブルは要素を内部の配列に格納し、各要素のハッシュコードにより格納する位置を決定する。 並列可変ハッシュ集合 ( -[mutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-version}}/scala/collection/parallel/mutable/ParHashSet.html)) -と並列可変ハッシュマップ ([mutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/mutable/ParHashMap.html)) +[mutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-212-version}}/scala/collection/parallel/mutable/ParHashSet.html)) +と並列可変ハッシュマップ ([mutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/mutable/ParHashMap.html)) はハッシュテーブルに基づいている。 scala> val phs = scala.collection.parallel.mutable.ParHashSet(1 until 2000: _*) @@ -100,8 +100,8 @@ language: ja ## 並列ハッシュトライ 並列ハッシュトライは、不変集合と不変マップを効率的に表す不変ハッシュトライの並列版だ。 -これらは、[immutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/immutable/ParHashSet.html) クラスと -[immutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-version}}/scala/collection/parallel/immutable/ParHashMap.html) クラスにより提供される。 +これらは、[immutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/immutable/ParHashSet.html) クラスと +[immutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-212-version}}/scala/collection/parallel/immutable/ParHashMap.html) クラスにより提供される。 scala> val phs = scala.collection.parallel.immutable.ParHashSet(1 until 1000: _*) phs: scala.collection.parallel.immutable.ParHashSet[Int] = ParSet(645, 892, 69, 809, 629, 365, 138, 760, 101, 479,... @@ -115,9 +115,9 @@ language: ja ## 並列並行トライ -[concurrent.TrieMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/concurrent/TrieMap.html) +[concurrent.TrieMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/concurrent/TrieMap.html) は、複数のスレッドから同時にアクセスできる (concurrent thread-safe) マップだが、 -[mutable.ParTrieMap](http://www.scala-lang.org/api/{{ site.scala-version}}/scala/collection/parallel/mutable/ParTrieMap.html) +[mutable.ParTrieMap](http://www.scala-lang.org/api/{{ site.scala-212-version}}/scala/collection/parallel/mutable/ParTrieMap.html) は、その並列版だ。 並列データ構造の多くは、走査時にデータ構造が変更された場合に一貫性のある走査を保証しないが、並行トライは更新が次回の走査まで見えないことを保証する。 つまり以下の 1 から 99 の数の平方根を出力する例のように、並行トライを走査中に変更できるようになる: diff --git a/_ko/tour/annotations.md b/_ko/tour/annotations.md index 4e2cba3524..e4674f5bbc 100644 --- a/_ko/tour/annotations.md +++ b/_ko/tour/annotations.md @@ -27,7 +27,6 @@ previous-page: automatic-closures | [`scala.deprecated`](https://www.scala-lang.org/api/current/scala/deprecated.html) | [`java.lang.Deprecated`](http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Deprecated.html) | | [`scala.inline`](https://www.scala-lang.org/api/current/scala/inline.html) (2.6.0 부터) | 해당 없음 | | [`scala.native`](https://www.scala-lang.org/api/current/scala/native.html) (2.6.0 부터) | [`native`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (키워드) | -| [`scala.remote`](https://www.scala-lang.org/api/current/scala/remote.html) | [`java.rmi.Remote`](http://java.sun.com/j2se/1.5.0/docs/api/java/rmi/Remote.html) | | [`scala.throws`](https://www.scala-lang.org/api/current/scala/throws.html) | [`throws`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (키워드) | | [`scala.transient`](https://www.scala-lang.org/api/current/scala/transient.html) | [`transient`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (키워드) | | [`scala.unchecked`](https://www.scala-lang.org/api/current/scala/unchecked.html) (2.4.0 부터) | 해당 없음 | diff --git a/_overviews/collections/trait-traversable.md b/_overviews/collections/trait-traversable.md index ad749d8097..fe048347ec 100644 --- a/_overviews/collections/trait-traversable.md +++ b/_overviews/collections/trait-traversable.md @@ -44,7 +44,7 @@ The `foreach` method is meant to traverse all elements of the collection, and ap | **Abstract Method:** | | | `xs foreach f` |Executes function `f` for every element of `xs`.| | **Addition:** | | -| `xs ++ ys` |A collection consisting of the elements of both `xs` and `ys`. `ys` is a [TraversableOnce](http://www.scala-lang.org/api/current/scala/collection/TraversableOnce.html) collection, i.e., either a [Traversable](http://www.scala-lang.org/api/current/scala/collection/Traversable.html) or an [Iterator](http://www.scala-lang.org/api/current/scala/collection/Iterator.html).| +| `xs ++ ys` |A collection consisting of the elements of both `xs` and `ys`. `ys` is a [TraversableOnce](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/TraversableOnce.html) collection, i.e., either a [Traversable](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Traversable.html) or an [Iterator](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterator.html).| | **Maps:** | | | `xs map f` |The collection obtained from applying the function f to every element in `xs`.| | `xs flatMap f` |The collection obtained from applying the collection-valued function `f` to every element in `xs` and concatenating the results.| diff --git a/_pl/tour/annotations.md b/_pl/tour/annotations.md index 65921a156f..70feceffde 100644 --- a/_pl/tour/annotations.md +++ b/_pl/tour/annotations.md @@ -26,7 +26,6 @@ Znaczenie adnotacji jest zależne od implementacji. Na platformie Java poniższe | [`scala.deprecated`](https://www.scala-lang.org/api/current/scala/deprecated.html) | [`java.lang.Deprecated`](http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Deprecated.html) | | [`scala.inline`](https://www.scala-lang.org/api/current/scala/inline.html) (since 2.6.0) | brak odpowiednika | | [`scala.native`](https://www.scala-lang.org/api/current/scala/native.html) (since 2.6.0) | [`native`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (słowo kluczowe) | -| [`scala.remote`](https://www.scala-lang.org/api/current/scala/remote.html) | [`java.rmi.Remote`](http://java.sun.com/j2se/1.5.0/docs/api/java/rmi/Remote.html) | | [`scala.throws`](https://www.scala-lang.org/api/current/scala/throws.html) | [`throws`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (słowo kluczowe) | | [`scala.transient`](https://www.scala-lang.org/api/current/scala/transient.html) | [`transient`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (słowo kluczowe) | | [`scala.unchecked`](https://www.scala-lang.org/api/current/scala/unchecked.html) (od 2.4.0) | brak odpowiednika | diff --git a/_pt-br/tour/annotations.md b/_pt-br/tour/annotations.md index 3b262897de..1ae94788c7 100644 --- a/_pt-br/tour/annotations.md +++ b/_pt-br/tour/annotations.md @@ -26,7 +26,6 @@ O significado das cláusulas de anotação é _dependente da implementação_. N | [`scala.deprecated`](https://www.scala-lang.org/api/current/scala/deprecated.html) | [`java.lang.Deprecated`](http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Deprecated.html) | | [`scala.inline`](https://www.scala-lang.org/api/current/scala/inline.html) (desde 2.6.0) | não há equivalente | | [`scala.native`](https://www.scala-lang.org/api/current/scala/native.html) (desde 2.6.0) | [`native`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (keyword) | -| [`scala.remote`](https://www.scala-lang.org/api/current/scala/remote.html) | [`java.rmi.Remote`](http://java.sun.com/j2se/1.5.0/docs/api/java/rmi/Remote.html) | | [`scala.throws`](https://www.scala-lang.org/api/current/scala/throws.html) | [`throws`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (keyword) | | [`scala.transient`](https://www.scala-lang.org/api/current/scala/transient.html) | [`transient`](http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html) (keyword) | | [`scala.unchecked`](https://www.scala-lang.org/api/current/scala/unchecked.html) (since 2.4.0) | não há equivalente | diff --git a/_zh-cn/overviews/collections/overview.md b/_zh-cn/overviews/collections/overview.md index 26d5e90771..3d2391a12e 100644 --- a/_zh-cn/overviews/collections/overview.md +++ b/_zh-cn/overviews/collections/overview.md @@ -20,7 +20,7 @@ Scala 集合类系统地区分了可变的和不可变的集合。可变集合 `scala.collection.mutable`包的集合类则有一些操作可以修改集合。所以处理可变集合意味着你需要去理解哪些代码的修改会导致集合同时改变。 -`scala.collection`包中的集合,既可以是可变的,也可以是不可变的。例如:[collection.IndexedSeq[T]](http://www.scala-lang.org/api/current/scala/collection/IndexedSeq.html)] 就是 [collection.immutable.IndexedSeq[T]](http://www.scala-lang.org/api/current/scala/collection/immutable/IndexedSeq.html) 和[collection.mutable.IndexedSeq[T]](http://www.scala-lang.org/api/current/scala/collection/mutable/IndexedSeq.html)这两类的超类。`scala.collection`包中的根集合类中定义了相同的接口作为不可变集合类,同时,`scala.collection.mutable`包中的可变集合类代表性的添加了一些有辅助作用的修改操作到这个immutable 接口。 +`scala.collection`包中的集合,既可以是可变的,也可以是不可变的。例如:[collection.IndexedSeq[T]](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/IndexedSeq.html)] 就是 [collection.immutable.IndexedSeq[T]](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/IndexedSeq.html) 和[collection.mutable.IndexedSeq[T]](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/IndexedSeq.html)这两类的超类。`scala.collection`包中的根集合类中定义了相同的接口作为不可变集合类,同时,`scala.collection.mutable`包中的可变集合类代表性的添加了一些有辅助作用的修改操作到这个immutable 接口。 根集合类与不可变集合类之间的区别是不可变集合类的客户端可以确保没有人可以修改集合。然而,根集合类的客户端仅保证不修改集合本身。即使这个集合类没有提供修改集合的静态操作,它仍然可能在运行时作为可变集合被其它客户端所修改。 @@ -41,7 +41,7 @@ Scala 集合类系统地区分了可变的和不可变的集合。可变集合 List // 因为scala._ // 总是是被自动导入。 -其它类型的别名有: [Traversable](http://www.scala-lang.org/api/current/scala/collection/Traversable.html), [Iterable](http://www.scala-lang.org/api/current/scala/collection/Iterable.html), [Seq](http://www.scala-lang.org/api/current/scala/collection/Seq.html), [IndexedSeq](http://www.scala-lang.org/api/current/scala/collection/IndexedSeq.html), [Iterator](http://www.scala-lang.org/api/current/scala/collection/Iterator.html), [Stream](http://www.scala-lang.org/api/current/scala/collection/immutable/Stream.html), [Vector](http://www.scala-lang.org/api/current/scala/collection/immutable/Vector.html), [StringBuilder](http://www.scala-lang.org/api/current/scala/collection/mutable/StringBuilder.html), [Range](http://www.scala-lang.org/api/current/scala/collection/immutable/Range.html)。 +其它类型的别名有: [Traversable](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Traversable.html), [Iterable](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterable.html), [Seq](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Seq.html), [IndexedSeq](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/IndexedSeq.html), [Iterator](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterator.html), [Stream](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Stream.html), [Vector](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Vector.html), [StringBuilder](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/StringBuilder.html), [Range](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Range.html)。 下面的图表显示了`scala.collection`包中所有的集合类。这些都是高级抽象类或特性,它们通常具备和不可变实现一样的可变实现。 From f6431aae58c113fe6a3be8a193892149887a977d Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Tue, 11 Jun 2019 07:57:25 +0200 Subject: [PATCH 0531/3075] Reorder and retitle the collection guides --- _data/overviews.yml | 94 ++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/_data/overviews.yml b/_data/overviews.yml index 0b5470023e..bfc4c293ed 100644 --- a/_data/overviews.yml +++ b/_data/overviews.yml @@ -2,53 +2,6 @@ - category: Standard Library description: "Guides and overviews covering the Scala standard library." overviews: - - title: Collections - by: Martin Odersky - icon: sitemap - url: "collections/introduction.html" - description: "Scala's Collection Library." - subdocs: - - title: Introduction - url: "collections/introduction.html" - - title: Mutable and Immutable Collections - url: "collections/overview.html" - - title: Trait Traversable - url: "collections/trait-traversable.html" - - title: Trait Iterable - url: "collections/trait-iterable.html" - - title: The sequence traits Seq, IndexedSeq, and LinearSeq - url: "collections/seqs.html" - - title: Sets - url: "collections/sets.html" - - title: Maps - url: "collections/maps.html" - - title: Concrete Immutable Collection Classes - url: "collections/concrete-immutable-collection-classes.html" - - title: Concrete Mutable Collection Classes - url: "collections/concrete-mutable-collection-classes.html" - - title: Arrays - url: "collections/arrays.html" - - title: Strings - url: "collections/strings.html" - - title: Performance Characteristics - url: "collections/performance-characteristics.html" - - title: Equality - url: "collections/equality.html" - - title: Views - url: "collections/views.html" - - title: Iterators - url: "collections/iterators.html" - - title: Creating Collections From Scratch - url: "collections/creating-collections-from-scratch.html" - - title: Conversions Between Java and Scala Collections - url: "collections/conversions-between-java-and-scala-collections.html" - - title: Migrating from Scala 2.7 - url: "collections/migrating-from-scala-27.html" - - title: The Architecture of Scala Collections - icon: building - url: "core/architecture-of-scala-collections.html" - by: Martin Odersky and Lex Spoon - description: "These pages describe the architecture of the Scala collections framework in detail. Compared to the Collections API you will find out more about the internal workings of the framework. You will also learn how this architecture helps you define your own collections in a few lines of code, while reusing the overwhelming part of collection functionality from the framework." - title: Scala 2.13’s Collections by: Martin Odersky and Julien Richard-Foy icon: sitemap @@ -102,6 +55,53 @@ url: "core/custom-collection-operations.html" by: Julien Richard-Foy description: "This guide shows how to write operations that can be applied to any collection type and return the same collection type, and how to write operations that can be parameterized by the type of collection to build." + - title: Scala 2.8 to 2.12’s Collections + by: Martin Odersky + icon: sitemap + url: "collections/introduction.html" + description: "Scala's Collection Library." + subdocs: + - title: Introduction + url: "collections/introduction.html" + - title: Mutable and Immutable Collections + url: "collections/overview.html" + - title: Trait Traversable + url: "collections/trait-traversable.html" + - title: Trait Iterable + url: "collections/trait-iterable.html" + - title: The sequence traits Seq, IndexedSeq, and LinearSeq + url: "collections/seqs.html" + - title: Sets + url: "collections/sets.html" + - title: Maps + url: "collections/maps.html" + - title: Concrete Immutable Collection Classes + url: "collections/concrete-immutable-collection-classes.html" + - title: Concrete Mutable Collection Classes + url: "collections/concrete-mutable-collection-classes.html" + - title: Arrays + url: "collections/arrays.html" + - title: Strings + url: "collections/strings.html" + - title: Performance Characteristics + url: "collections/performance-characteristics.html" + - title: Equality + url: "collections/equality.html" + - title: Views + url: "collections/views.html" + - title: Iterators + url: "collections/iterators.html" + - title: Creating Collections From Scratch + url: "collections/creating-collections-from-scratch.html" + - title: Conversions Between Java and Scala Collections + url: "collections/conversions-between-java-and-scala-collections.html" + - title: Migrating from Scala 2.7 + url: "collections/migrating-from-scala-27.html" + - title: The Architecture of Scala 2.8 to 2.12’s Collections + icon: building + url: "core/architecture-of-scala-collections.html" + by: Martin Odersky and Lex Spoon + description: "These pages describe the architecture of the Scala collections framework in detail. Compared to the Collections API you will find out more about the internal workings of the framework. You will also learn how this architecture helps you define your own collections in a few lines of code, while reusing the overwhelming part of collection functionality from the framework." - category: Language description: "Guides and overviews covering features in the Scala language." From 6e177b98b9752e80dd3cae77ff37ae37fb8738aa Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Mon, 24 Jun 2019 07:51:13 +0100 Subject: [PATCH 0532/3075] Fix links, take 3 --- _overviews/collections/overview.md | 8 ++++---- .../concrete-parallel-collections.md | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/_overviews/collections/overview.md b/_overviews/collections/overview.md index a394241837..41bdf6ff39 100644 --- a/_overviews/collections/overview.md +++ b/_overviews/collections/overview.md @@ -41,10 +41,10 @@ mutable collection means you need to understand which code changes which collection when. A collection in package `scala.collection` can be either mutable or -immutable. For instance, [collection.IndexedSeq\[T\]](http://www.scala-lang.org/api/current/scala/collection/IndexedSeq.html) -is a superclass of both [collection.immutable.IndexedSeq\[T\]](http://www.scala-lang.org/api/current/scala/collection/immutable/IndexedSeq.html) +immutable. For instance, [collection.IndexedSeq\[T\]](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/IndexedSeq.html) +is a superclass of both [collection.immutable.IndexedSeq\[T\]](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/IndexedSeq.html) and -[collection.mutable.IndexedSeq\[T\]](http://www.scala-lang.org/api/current/scala/collection/mutable/IndexedSeq.html) +[collection.mutable.IndexedSeq\[T\]](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/IndexedSeq.html) Generally, the root collections in package `scala.collection` define the same interface as the immutable collections, and the mutable collections in package @@ -94,7 +94,7 @@ can be accessed alternatively as // is always automatically imported Other types aliased are -[Traversable](http://www.scala-lang.org/api/current/scala/collection/Traversable.html), [Iterable](http://www.scala-lang.org/api/current/scala/collection/Iterable.html), [Seq](http://www.scala-lang.org/api/current/scala/collection/Seq.html), [IndexedSeq](http://www.scala-lang.org/api/current/scala/collection/IndexedSeq.html), [Iterator](http://www.scala-lang.org/api/current/scala/collection/Iterator.html), [Stream](http://www.scala-lang.org/api/current/scala/collection/immutable/Stream.html), [Vector](http://www.scala-lang.org/api/current/scala/collection/immutable/Vector.html), [StringBuilder](http://www.scala-lang.org/api/current/scala/collection/mutable/StringBuilder.html), and [Range](http://www.scala-lang.org/api/current/scala/collection/immutable/Range.html). +[Traversable](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Traversable.html), [Iterable](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterable.html), [Seq](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Seq.html), [IndexedSeq](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/IndexedSeq.html), [Iterator](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterator.html), [Stream](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Stream.html), [Vector](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Vector.html), [StringBuilder](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/mutable/StringBuilder.html), and [Range](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Range.html). The following figure shows all collections in package `scala.collection`. These are all high-level abstract classes or traits, which diff --git a/_ru/overviews/parallel-collections/concrete-parallel-collections.md b/_ru/overviews/parallel-collections/concrete-parallel-collections.md index f0985016b8..7dc087e280 100644 --- a/_ru/overviews/parallel-collections/concrete-parallel-collections.md +++ b/_ru/overviews/parallel-collections/concrete-parallel-collections.md @@ -13,7 +13,7 @@ num: 2 ## Параллельный Массив -Последовательность [ParArray](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/mutable/ParArray.html) хранит линейный массив смежно хранимых элементов. Это означает, что получение доступа и обновление элементов эффективно, так как происходит путем изменения массива, лежащего в основе. По этой причине наиболее эффективна последовательная обработка элементов одного за другим. Параллельные массивы похожи на обычные в том отношении, что их размер постоянен. +Последовательность [ParArray](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/mutable/ParArray.html) хранит линейный массив смежно хранимых элементов. Это означает, что получение доступа и обновление элементов эффективно, так как происходит путем изменения массива, лежащего в основе. По этой причине наиболее эффективна последовательная обработка элементов одного за другим. Параллельные массивы похожи на обычные в том отношении, что их размер постоянен. scala> val pa = scala.collection.parallel.mutable.ParArray.tabulate(1000)(x => 2 * x + 1) pa: scala.collection.parallel.mutable.ParArray[Int] = ParArray(1, 3, 5, 7, 9, 11, 13,... @@ -30,7 +30,7 @@ num: 2 ## Параллельный вектор -[ParVector](http://www.scala-lang.org/api/{{ site.scala-version}}/scala/collection/parallel/immutable/ParVector.html) является неизменяемой последовательностью, временная сложность доступа и обновления которой является логарифмической с низкой константой-множителем. +[ParVector](http://www.scala-lang.org/api/{{ site.scala-212-version}}/scala/collection/parallel/immutable/ParVector.html) является неизменяемой последовательностью, временная сложность доступа и обновления которой является логарифмической с низкой константой-множителем. scala> val pv = scala.collection.parallel.immutable.ParVector.tabulate(1000)(x => x) pv: scala.collection.parallel.immutable.ParVector[Int] = ParVector(0, 1, 2, 3, 4, 5, 6, 7, 8, 9,... @@ -41,11 +41,11 @@ num: 2 Неизменяемые векторы представлены 32-ичными деревьями (32-way trees), поэтому [разделители]({{ site.baseurl }}/ru/overviews/parallel-collections/architecture.html) разбивают их, назначая по поддереву каждому новому разделителю. [Компоновщики]({{ site.baseurl }}/ru/overviews/parallel-collections/architecture.html) в настоящий момент хранят вектор из элементов и компонуют путем отложенного копирования. По этой причине методы трансформации менее масштабируемы по сравнению с теми же методами параллельного массива. Как только в будущем релизе Scala станет доступной операция конкатенации векторов, компоновщики станут образовываться путем конкатенации, и от этого методы трансформации станут гораздо более эффективными. -Параллельный вектор является параллельным аналогом последовательной коллекции [Vector](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Vector.html), и преобразования одного в другое занимают постоянное время. +Параллельный вектор является параллельным аналогом последовательной коллекции [Vector](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Vector.html), и преобразования одного в другое занимают постоянное время. ## Параллельный диапазон -[ParRange](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/immutable/ParRange.html) представляет собой упорядоченную последовательность элементов, отстоящих друг от друга на одинаковые промежутки. Параллельный диапазон создается подобно последовательному [Range](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/immutable/Range.html): +[ParRange](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/immutable/ParRange.html) представляет собой упорядоченную последовательность элементов, отстоящих друг от друга на одинаковые промежутки. Параллельный диапазон создается подобно последовательному [Range](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/immutable/Range.html): scala> 1 to 3 par res0: scala.collection.parallel.immutable.ParRange = ParRange(1, 2, 3) @@ -57,7 +57,7 @@ num: 2 ## Параллельные хэш-таблицы -В основе параллельной хэш-таблицы лежит массив, причем место элемента таблицы в этом массиве определяется хэш-кодом элемента. На хэш-таблицах основаны параллельные изменяемые хэш-множества ([mutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-version}}/scala/collection/parallel/mutable/ParHashSet.html)) и параллельные изменяемые ассоциативные хэш-массивы (хэш-отображения) ([mutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/mutable/ParHashMap.html)). +В основе параллельной хэш-таблицы лежит массив, причем место элемента таблицы в этом массиве определяется хэш-кодом элемента. На хэш-таблицах основаны параллельные изменяемые хэш-множества ([mutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-212-version}}/scala/collection/parallel/mutable/ParHashSet.html)) и параллельные изменяемые ассоциативные хэш-массивы (хэш-отображения) ([mutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/mutable/ParHashMap.html)). scala> val phs = scala.collection.parallel.mutable.ParHashSet(1 until 2000: _*) phs: scala.collection.parallel.mutable.ParHashSet[Int] = ParHashSet(18, 327, 736, 1045, 773, 1082,... @@ -71,7 +71,7 @@ num: 2 ## Параллельные префиксные хэш-деревья (Hash Tries) -Параллельные префиксные хэш-деревья являются параллельным аналогом неизменяемых префиксных хэш-деревьев, которые используются для эффективного представления неизменяемых множеств и ассоциативных массивов. Последние представлены классами [immutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/parallel/immutable/ParHashSet.html) и [immutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-version}}/scala/collection/parallel/immutable/ParHashMap.html). +Параллельные префиксные хэш-деревья являются параллельным аналогом неизменяемых префиксных хэш-деревьев, которые используются для эффективного представления неизменяемых множеств и ассоциативных массивов. Последние представлены классами [immutable.ParHashSet](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/parallel/immutable/ParHashSet.html) и [immutable.ParHashMap](http://www.scala-lang.org/api/{{ site.scala-212-version}}/scala/collection/parallel/immutable/ParHashMap.html). scala> val phs = scala.collection.parallel.immutable.ParHashSet(1 until 1000: _*) phs: scala.collection.parallel.immutable.ParHashSet[Int] = ParSet(645, 892, 69, 809, 629, 365, 138, 760, 101, 479,... @@ -85,7 +85,7 @@ num: 2 ## Параллельные многопоточные префиксные деревья (Concurrent Tries) -Параллельным аналогом коллекции [concurrent.TrieMap](http://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/concurrent/TrieMap.html), представляющей собой многопоточный и потокозащищеный ассоциативный массив, является коллекция [mutable.ParTrieMap](http://www.scala-lang.org/api/{{ site.scala-version}}/scala/collection/parallel/mutable/ParTrieMap.html). В то время, как большинство многопоточных структур данных не гарантируют правильного перебора элементов в случае, если эта структура данных была изменена во время ее прохождения, многопоточные деревья `Ctries` гарантируют, что обновленные данные станут видны только при следующем прохождении. Это означает, что можно изменять многопоточное дерево прямо во время прохождения, как в следующем примере, в котором выводятся квадратные корни от 1 до 99: +Параллельным аналогом коллекции [concurrent.TrieMap](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/concurrent/TrieMap.html), представляющей собой многопоточный и потокозащищеный ассоциативный массив, является коллекция [mutable.ParTrieMap](http://www.scala-lang.org/api/{{ site.scala-212-version}}/scala/collection/parallel/mutable/ParTrieMap.html). В то время, как большинство многопоточных структур данных не гарантируют правильного перебора элементов в случае, если эта структура данных была изменена во время ее прохождения, многопоточные деревья `Ctries` гарантируют, что обновленные данные станут видны только при следующем прохождении. Это означает, что можно изменять многопоточное дерево прямо во время прохождения, как в следующем примере, в котором выводятся квадратные корни от 1 до 99: scala> val numbers = scala.collection.parallel.mutable.ParTrieMap((1 until 100) zip (1 until 100): _*) map { case (k, v) => (k.toDouble, v.toDouble) } numbers: scala.collection.parallel.mutable.ParTrieMap[Double,Double] = ParTrieMap(0.0 -> 0.0, 42.0 -> 42.0, 70.0 -> 70.0, 2.0 -> 2.0,... From 37f64a196bb756d7bc85ac845741b248d7ddd5c6 Mon Sep 17 00:00:00 2001 From: Dale Wijnand <344610+dwijnand@users.noreply.github.com> Date: Sun, 23 Jun 2019 14:40:24 +0100 Subject: [PATCH 0533/3075] Rebrand MiMa & clarify recommended version scheme --- ...binary-compatibility-for-library-authors.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/_overviews/tutorials/binary-compatibility-for-library-authors.md b/_overviews/tutorials/binary-compatibility-for-library-authors.md index 655317c95d..79efcdc29b 100644 --- a/_overviews/tutorials/binary-compatibility-for-library-authors.md +++ b/_overviews/tutorials/binary-compatibility-for-library-authors.md @@ -143,11 +143,11 @@ How can we, as library authors, spare our users of runtime errors and dependency ## MiMa - Checking binary compatibility against previous library versions -The [Migration Manager for Scala](https://github.com/lightbend/migration-manager) (MiMa) is a tool for diagnosing binary incompatibilities between different library versions. +[MiMa](https://github.com/lightbend/mima) is a tool for diagnosing binary incompatibilities between different library versions. It works by comparing the class files of two provided JARs and report any binary incompatibilities found. Both backwards and forwards binary incompatibility can be detected by swapping input order of the JARs. -By incorporating MiMa's [sbt plugin](https://github.com/lightbend/migration-manager/wiki/sbt-plugin) into your sbt build, you can easily check whether +By incorporating MiMa's [sbt plugin](https://github.com/lightbend/mima/wiki/sbt-plugin) into your sbt build, you can easily check whether you have accidentally introduced binary incompatible changes. Detailed instruction on how to use the sbt plugin can be found in the link. We strongly encourage every library author to incorporate MiMa into their continuous integration and release workflow. @@ -175,7 +175,7 @@ Again, we recommend using MiMa to double check that you have not broken binary c ## Versioning Scheme - Communicating compatibility breakages -Library authors use versioning schemes to communicate compatibility guarantees between library releases to their users. Versioning schemes like [Semantic Versioning](http://semver.org/)(SemVer) allow +Library authors use versioning schemes to communicate compatibility guarantees between library releases to their users. Versioning schemes like [Semantic Versioning](http://semver.org/) (SemVer) allow users to easily reason about the impact of updating a library, without needing to read the detailed release notes. In the following section, we will outline a versioning scheme based on Semantic Versioning that we **strongly encourage** you to adopt for your libraries. The rules listed below are **in addition** to @@ -183,12 +183,16 @@ Semantic Versioning v2.0.0. ### Recommended Versioning Scheme -* If backward **binary compatibility** is broken, **major version number** must be increased. -* If backward **source compatibility** is broken, **minor version number** must be increased. -* A change in **patch version number** signals **neither binary nor source incompatibility**. +Given a version number MAJOR.MINOR.PATCH, you MUST increment the: + +1. MAJOR version if backward **binary compatibility** is broken, +2. MINOR version if backward **source compatibility** is broken, and +3. PATCH version to signal **neither binary nor source incompatibility**. + According to SemVer, patch versions should contain only bug fixes that fix incorrect behavior so major behavioral change in method/classes should result in a minor version bump. -* When major version is `0`, a minor version bump **may contain both source and binary breakages**. + +* When the major version is `0`, a minor version bump **may contain both source and binary breakages**. Some examples: From dc06ff3c20e7464a100fc65869b04294daee1296 Mon Sep 17 00:00:00 2001 From: Dale Wijnand <344610+dwijnand@users.noreply.github.com> Date: Mon, 24 Jun 2019 10:07:33 +0100 Subject: [PATCH 0534/3075] Drop the reference to SLIPs --- _sips/sip-tutorial.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_sips/sip-tutorial.md b/_sips/sip-tutorial.md index b5ed7e03ae..24d1577a0d 100644 --- a/_sips/sip-tutorial.md +++ b/_sips/sip-tutorial.md @@ -10,7 +10,7 @@ This tutorial details of how to write a new SIP and adding it to the website. The process to submit is simple: * Fork the [Scala documentation repository](http://github.com/scala/docs.scala-lang) and clone it. -* Create a new SIP file in the `sips/pending/_posts/`. Use the [S(L)IP template](https://github.com/scala/docs.scala-lang/blob/master/_sips/sip-template.md) +* Create a new SIP file in the `sips/pending/_posts/`. Use the [SIP template](https://github.com/scala/docs.scala-lang/blob/master/_sips/sip-template.md) * Make sure the new file follows the format: `YYYY-MM-dd-{title}.md`. Use the proposal date for `YYYY-MM-dd`. * Use the [Markdown Syntax](http://daringfireball.net/projects/markdown/syntax) to write your SIP. * Follow the instructions in the [README](https://github.com/scala/docs.scala-lang/blob/master/README.md) to build your SIP locally so you can ensure that it looks correct on the website. From 50f3d29704c7e05ca34583c6b83c5fb4c4f3f5c6 Mon Sep 17 00:00:00 2001 From: Dale Wijnand <344610+dwijnand@users.noreply.github.com> Date: Mon, 24 Jun 2019 10:53:48 +0100 Subject: [PATCH 0535/3075] Add 2.13.0 to the JDK compatibility table --- _overviews/jdk-compatibility/overview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_overviews/jdk-compatibility/overview.md b/_overviews/jdk-compatibility/overview.md index 117e52b90b..57d9e3d7b3 100644 --- a/_overviews/jdk-compatibility/overview.md +++ b/_overviews/jdk-compatibility/overview.md @@ -18,8 +18,8 @@ This table shows the first Scala release in each series that works with each JVM | JVM version | Minimum Scala versions | |:-----------:|:----------------------------------------------------------------------------------------------| | 12 | see [below](#jdk-12-compatibility-notes) | -| 11 | 2.12.4, 2.11.12, 2.10.7 (but also, see [below](#jdk-11-compatibility-notes)) | -| 8 | 2.12.0, 2.11.0, 2.10.2 | +| 11 | 2.13.0, 2.12.4, 2.11.12, 2.10.7 (but also, see [below](#jdk-11-compatibility-notes)) | +| 8 | 2.13.0, 2.12.0, 2.11.0, 2.10.2 | | 7 | 2.11.0, 2.10.0 | | 6 | 2.11.0, 2.10.0 | From 5a501aa966675623c714bb848202eaaf545a5f0f Mon Sep 17 00:00:00 2001 From: alex-t-wix <47665163+alex-t-wix@users.noreply.github.com> Date: Mon, 24 Jun 2019 14:54:25 +0300 Subject: [PATCH 0536/3075] Clarifying first limitation of value-classes Phrase "... val parameter whose type is not a value class" seems wrong. You actually can have value class as a parameter but it must be a standard value class. I suggest using term "user-defined value class". --- _overviews/core/value-classes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/core/value-classes.md b/_overviews/core/value-classes.md index 9b9d0c06a4..06cba3d4cb 100644 --- a/_overviews/core/value-classes.md +++ b/_overviews/core/value-classes.md @@ -140,7 +140,7 @@ Full details on the implementation of value classes and their limitations may be A value class ... -1. ... must have only a primary constructor with exactly one public, val parameter whose type is not a value class. (From Scala 2.11.0, the parameter may be non-public.) +1. ... must have only a primary constructor with exactly one public, val parameter whose type is not a user-defined value class. (From Scala 2.11.0, the parameter may be non-public.) 2. ... may not have specialized type parameters. 3. ... may not have nested or local classes, traits, or objects 4. ... may not define a equals or hashCode method. From 2927896954776c1d3144078e4f742cab59ac4696 Mon Sep 17 00:00:00 2001 From: Dale Wijnand <344610+dwijnand@users.noreply.github.com> Date: Mon, 24 Jun 2019 14:07:38 +0100 Subject: [PATCH 0537/3075] Add 2.13.0 to JDK 11 compat notes --- _overviews/jdk-compatibility/overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/jdk-compatibility/overview.md b/_overviews/jdk-compatibility/overview.md index 57d9e3d7b3..92ae69b088 100644 --- a/_overviews/jdk-compatibility/overview.md +++ b/_overviews/jdk-compatibility/overview.md @@ -43,7 +43,7 @@ Like the 2.12.x series, the Scala 2.13.x series will support Java 8 and higher. Although the table above jumps from 8 to 11, JDK 9 and 10 will probably also work wherever 11 does. But unlike 9 and 10, 11 is an LTS release, so 11 is what we actually test on and recommend. -As of Scala 2.12.8 and 2.11.12, **JDK 11 support is incomplete**. Notably, `scalac` will not enforce the restrictions of the Java Platform Module System, which means that code that typechecks may incur linkage errors at runtime. Scala 2.13.x will eventually provide [rudimentary support](https://github.com/scala/scala/pull/7218) for this, but likely only in nightlies built on Java 11. +As of Scala 2.13.0, 2.12.8 and 2.11.12, **JDK 11 support is incomplete**. Notably, `scalac` will not enforce the restrictions of the Java Platform Module System, which means that code that typechecks may incur linkage errors at runtime. Scala 2.13.x will eventually provide [rudimentary support](https://github.com/scala/scala/pull/7218) for this, but likely only in nightlies built on Java 11. JDK 11 support requires minimum sbt version 1.1.0, or 0.13.17 in the 0.13.x series. From 771034b0b2c2fed5e38e8775bc671948a4317887 Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Tue, 25 Jun 2019 11:39:21 +0800 Subject: [PATCH 0538/3075] (overview) Fix zh-cn in pr#1398, with more fixes of the same page. --- _zh-cn/overviews/core/value-classes.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_zh-cn/overviews/core/value-classes.md b/_zh-cn/overviews/core/value-classes.md index b731b9da0e..d19501d7e4 100644 --- a/_zh-cn/overviews/core/value-classes.md +++ b/_zh-cn/overviews/core/value-classes.md @@ -123,9 +123,9 @@ value类在以下情况下,需要真正实例化: 一个value类 ... -1. ... 必须只有一个public的构造函数。并有且只有一个public的,类型不为value类的val参数。 -2. ... 不能有特殊的类型参数. -3. ... 不能有嵌套或本地类、trait或对象。 +1. ... 必须只有一个主构造器。该构造器有且仅有一个public修饰的不可变(val)参数,且参数的类型不是用户自定义的value类。 +2. ... 不能有特殊的类型参数。 +3. ... 不能有嵌套或局部的类、特质或对象。 4. ... 不能定义equals或hashCode方法。 5. ... 必须是一个顶级类,或静态访问对象的一个成员 6. ... 仅能有def为成员。尤其是,成员不能有惰性val、val或者var 。 From 160c8358f543ac056236226dae59f6d8af9b87d2 Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Tue, 25 Jun 2019 11:43:54 +0800 Subject: [PATCH 0539/3075] (overview) Fix zh-cn in pr#1398, with more polish-es. --- _zh-cn/overviews/core/value-classes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_zh-cn/overviews/core/value-classes.md b/_zh-cn/overviews/core/value-classes.md index d19501d7e4..2a2366e4d7 100644 --- a/_zh-cn/overviews/core/value-classes.md +++ b/_zh-cn/overviews/core/value-classes.md @@ -127,8 +127,8 @@ value类在以下情况下,需要真正实例化: 2. ... 不能有特殊的类型参数。 3. ... 不能有嵌套或局部的类、特质或对象。 4. ... 不能定义equals或hashCode方法。 -5. ... 必须是一个顶级类,或静态访问对象的一个成员 -6. ... 仅能有def为成员。尤其是,成员不能有惰性val、val或者var 。 +5. ... 必须是一个顶级类,或静态访问对象的一个成员。 +6. ... 仅能有def为成员。尤其是,成员不能有惰性val、val或者var。 7. ... 不能被其它类继承。 ### 限制示例 From c9275510fb5547ef302480d7356470aa850c11eb Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Tue, 25 Jun 2019 19:58:42 +0800 Subject: [PATCH 0540/3075] (overview) Improve one statement, add 's for user perspective. --- _overviews/collections-2.13/introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/collections-2.13/introduction.md b/_overviews/collections-2.13/introduction.md index a4ff432874..7d27aec31f 100644 --- a/_overviews/collections-2.13/introduction.md +++ b/_overviews/collections-2.13/introduction.md @@ -91,5 +91,5 @@ Furthermore, the `partition` operation is quite fast, and can be even faster on parallel collections on multiple cores. This document provides an in depth discussion of the APIs of the -Scala collections classes from a user perspective. It takes you on +Scala collections classes from a user's perspective. It takes you on a tour of all the fundamental classes and the methods they define. From d523cdec634ad56c0bbbdbbc07fae719f9a7043b Mon Sep 17 00:00:00 2001 From: take2 Date: Wed, 26 Jun 2019 07:33:08 +0900 Subject: [PATCH 0541/3075] Translation tour ja (#1387) Authored-By: take2webservice Reviewed by Yasuhiro Tatsuno and Eugene Yokota. --- _data/translations.yml | 2 +- _ja/tour/abstract-type-members.md | 79 ++++++ _ja/tour/annotations.md | 130 ++++++++++ _ja/tour/automatic-closures.md | 62 +++++ _ja/tour/basics.md | 325 ++++++++++++++++++++++++ _ja/tour/by-name-parameters.md | 45 ++++ _ja/tour/case-classes.md | 66 +++++ _ja/tour/classes.md | 131 ++++++++++ _ja/tour/compound-types.md | 54 ++++ _ja/tour/default-parameter-values.md | 50 ++++ _ja/tour/extractor-objects.md | 72 ++++++ _ja/tour/for-comprehensions.md | 77 ++++++ _ja/tour/generic-classes.md | 65 +++++ _ja/tour/higher-order-functions.md | 121 +++++++++ _ja/tour/implicit-conversions.md | 62 +++++ _ja/tour/implicit-parameters.md | 75 ++++++ _ja/tour/inner-classes.md | 91 +++++++ _ja/tour/lower-type-bounds.md | 76 ++++++ _ja/tour/mixin-class-composition.md | 84 ++++++ _ja/tour/multiple-parameter-lists.md | 79 ++++++ _ja/tour/named-arguments.md | 36 +++ _ja/tour/nested-functions.md | 40 +++ _ja/tour/operators.md | 88 +++++++ _ja/tour/package-objects.md | 73 ++++++ _ja/tour/packages-and-imports.md | 87 +++++++ _ja/tour/pattern-matching.md | 166 ++++++++++++ _ja/tour/polymorphic-methods.md | 39 +++ _ja/tour/regular-expression-patterns.md | 63 +++++ _ja/tour/self-types.md | 42 +++ _ja/tour/singleton-objects.md | 122 +++++++++ _ja/tour/tour-of-scala.md | 86 +++++++ _ja/tour/traits.md | 89 +++++++ _ja/tour/tuples.md | 79 ++++++ _ja/tour/type-inference.md | 74 ++++++ _ja/tour/unified-types.md | 97 +++++++ _ja/tour/upper-type-bounds.md | 60 +++++ _ja/tour/variances.md | 184 ++++++++++++++ 37 files changed, 3170 insertions(+), 1 deletion(-) create mode 100644 _ja/tour/abstract-type-members.md create mode 100644 _ja/tour/annotations.md create mode 100644 _ja/tour/automatic-closures.md create mode 100644 _ja/tour/basics.md create mode 100644 _ja/tour/by-name-parameters.md create mode 100644 _ja/tour/case-classes.md create mode 100644 _ja/tour/classes.md create mode 100644 _ja/tour/compound-types.md create mode 100644 _ja/tour/default-parameter-values.md create mode 100644 _ja/tour/extractor-objects.md create mode 100644 _ja/tour/for-comprehensions.md create mode 100644 _ja/tour/generic-classes.md create mode 100644 _ja/tour/higher-order-functions.md create mode 100644 _ja/tour/implicit-conversions.md create mode 100644 _ja/tour/implicit-parameters.md create mode 100644 _ja/tour/inner-classes.md create mode 100644 _ja/tour/lower-type-bounds.md create mode 100644 _ja/tour/mixin-class-composition.md create mode 100644 _ja/tour/multiple-parameter-lists.md create mode 100644 _ja/tour/named-arguments.md create mode 100644 _ja/tour/nested-functions.md create mode 100644 _ja/tour/operators.md create mode 100644 _ja/tour/package-objects.md create mode 100644 _ja/tour/packages-and-imports.md create mode 100644 _ja/tour/pattern-matching.md create mode 100644 _ja/tour/polymorphic-methods.md create mode 100644 _ja/tour/regular-expression-patterns.md create mode 100644 _ja/tour/self-types.md create mode 100644 _ja/tour/singleton-objects.md create mode 100644 _ja/tour/tour-of-scala.md create mode 100644 _ja/tour/traits.md create mode 100644 _ja/tour/tuples.md create mode 100644 _ja/tour/type-inference.md create mode 100644 _ja/tour/unified-types.md create mode 100644 _ja/tour/upper-type-bounds.md create mode 100644 _ja/tour/variances.md diff --git a/_data/translations.yml b/_data/translations.yml index 266b039905..56d0fd59cf 100644 --- a/_data/translations.yml +++ b/_data/translations.yml @@ -1,2 +1,2 @@ tour: - languages: [ba, es, ko, pt-br, pl, zh-cn, th, ru] + languages: [ba, es, ko, pt-br, pl, zh-cn, th, ru, ja] diff --git a/_ja/tour/abstract-type-members.md b/_ja/tour/abstract-type-members.md new file mode 100644 index 0000000000..f5821a7b74 --- /dev/null +++ b/_ja/tour/abstract-type-members.md @@ -0,0 +1,79 @@ +--- +layout: tour +title: 抽象型メンバー +language: ja + +discourse: true + +partof: scala-tour +num: 23 +next-page: compound-types +previous-page: inner-classes +topics: abstract type members +prerequisite-knowledge: variance, upper-type-bound + +redirect_from: "/tutorials/tour/abstract-types.html" +redirect_from: "/tour/abstract-types.html" +--- + +トレイトや抽象クラスのような抽象型は抽象型メンバーを持つことができます。 +これは具体的な実装で実際の型を定義するという意味です。 +こちらが例です。 + +```tut +trait Buffer { + type T + val element: T +} +``` +こちらでは、抽象型`type T`を定義しています。それは`element`の型を記述するために使われます。このトレイトを抽象クラスで継承し、より具体的にするために上限型境界を`T`に追加することができます。 + +```tut +abstract class SeqBuffer extends Buffer { + type U + type T <: Seq[U] + def length = element.length +} +``` +`T`の上限型境界の定義に出てきた、更に別の抽象型`U`の使い方に気をつけてください。この`class SeqBuffer`はこのバッファーの中にシーケンスのみを保持することができます。それは型`T`は新しい抽象型`U`を使った`Seq[U]`のサブタイプであると記述しているからです。 + +抽象型メンバーを持つトレイトと[クラス](classes.html)は無名クラスのインスタンス化と組み合わせてよく使われます。 +これを説明するために、今から整数のリストを参照するシーケンスバッファーを扱うプログラムを見てみます。 + +```tut +abstract class IntSeqBuffer extends SeqBuffer { + type U = Int +} + + +def newIntSeqBuf(elem1: Int, elem2: Int): IntSeqBuffer = + new IntSeqBuffer { + type T = List[U] + val element = List(elem1, elem2) + } +val buf = newIntSeqBuf(7, 8) +println("length = " + buf.length) +println("content = " + buf.element) +``` +ここで、ファクトリー`newIntSeqBuf`は抽象型`T`を具体的な型`List[Int]`に設定するために、`IntSeqBuf`(つまり`new IntSeqBuffer`)を無名クラスで実装します。 + +抽象型メンバーをクラスの型パラメータに変えることも、その逆も可能です。以下は上記コードの型パラメータのみを使うバージョンです。 + +```tut +abstract class Buffer[+T] { + val element: T +} +abstract class SeqBuffer[U, +T <: Seq[U]] extends Buffer[T] { + def length = element.length +} + +def newIntSeqBuf(e1: Int, e2: Int): SeqBuffer[Int, Seq[Int]] = + new SeqBuffer[Int, List[Int]] { + val element = List(e1, e2) + } + +val buf = newIntSeqBuf(7, 8) +println("length = " + buf.length) +println("content = " + buf.element) +``` +ここでは(`+T <: Seq[U]`)をメソッド`newIntSeqBuf`から戻されるオブジェクトの具体的なシーケンス実装の型を隠すために [変位指定アノテーション](variances.html)を使わなければなりません。さらに、抽象型メンバをパラメータで置換することができないケースがあります。 diff --git a/_ja/tour/annotations.md b/_ja/tour/annotations.md new file mode 100644 index 0000000000..88114954f1 --- /dev/null +++ b/_ja/tour/annotations.md @@ -0,0 +1,130 @@ +--- +layout: tour +title: アノテーション +language: ja + +discourse: true + +partof: scala-tour + +num: 32 +next-page: default-parameter-values +previous-page: by-name-parameters + +redirect_from: "/tutorials/tour/annotations.html" +--- + +アノテーションはメタ情報と定義を関連づけます。例えば、メソッドの前のアノテーション`@deprecated`はメソッドが使われたらコンパイラに警告を出力させます。 +``` +object DeprecationDemo extends App { + @deprecated("deprecation message", "release # which deprecates method") + def hello = "hola" + + hello +} +``` +これはコンパイルされますが、コンパイラは警告"there was one deprecation warning"を出力します。 + +アノテーション句はそれに続く最初の定義か宣言に適用されます。定義と宣言の前には1つ以上のアノテーション句を置くことができます。これらの句の順番は重要ではありません。 + + +## エンコーディングの正確性を保証するアノテーション +条件が一致しない場合にコンパイルを失敗させるアノテーションもあります。例えば、アノテーション`@tailrec`はメソッドが[末尾再帰](https://en.wikipedia.org/wiki/Tail_call)であると保証します。末尾再帰ではメモリ使用量が一定になります。こちらは階乗を計算するメソッドの中での使われ方です。 +```tut +import scala.annotation.tailrec + +def factorial(x: Int): Int = { + + @tailrec + def factorialHelper(x: Int, accumulator: Int): Int = { + if (x == 1) accumulator else factorialHelper(x - 1, accumulator * x) + } + factorialHelper(x, 1) +} +``` +`factorialHelper`メソッドは`@tailrec`を持ちます。`@tailrec`はメソッドが実際に末尾再帰であると保証します。もし`factorialHelper`の実装を以下のように変更すれば、失敗し +``` +import scala.annotation.tailrec + +def factorial(x: Int): Int = { + @tailrec + def factorialHelper(x: Int): Int = { + if (x == 1) 1 else x * factorialHelper(x - 1) + } + factorialHelper(x) +} +``` +"Recursive call not in tail position"というメッセージを受け取ります。 + + +## コード生成に影響するアノテーション +`@inline`のようなアノテーションは生成されたコードに影響します(つまり、アノテーションを使わなかった場合とでjarファイルのバイト数が異なる場合があります)。インライン化とは、メソッドを呼び出している箇所にメソッド本体のコードを挿入することを意味します。結果のバイトコードはより長くなりますが、上手くいけば実行が早くなります。アノテーション`@inline`を使ってもメソッドのインライン化が保証されるわけではありません。しかし、生成されたコードのサイズに関するヒューリスティックスが満たされた場合に限りコンパイラにインライン化をさせます。 + +### Javaのアノテーション ### +Javaと相互運用するScalaのコードを書いている時、記述するアノテーション構文は少し違います。 + +**注:** Javaアノテーションを使う場合、`-target:jvm-1.8`オプションを使ってください。 + +Javaには[アノテーション](https://docs.oracle.com/javase/tutorial/java/annotations/)の形をしたユーザー定義メタデータがあります。Javaのアノテーションの特徴は、要素の初期化のために名前と値のペアを指定する必要があることです。例えば、クラスのソースを追いかけるためのアノテーションが必要なとき、以下のように定義するかもしれません。 + +``` +@interface Source { + public String URL(); + public String mail(); +} +``` + +そして、それは以下のように適用されます。 + +``` +@Source(URL = "http://coders.com/", + mail = "support@coders.com") +public class MyClass extends TheirClass ... +``` + +Scalaでのアノテーションの適用はコンストラクタの呼び出しと似ています。Javaのアノテーションをインスタンス化するためには名前付き引数を使う必要があります。 + +``` +@Source(URL = "http://coders.com/", + mail = "support@coders.com") +class MyScalaClass ... +``` + +アノテーションが(デフォルト値を除き)要素を1つだけ含む場合、この構文はかなり退屈です。そのため慣例により、名前が`value`と指定されていれば、コンストラクタのような構文でJavaに適用できます。 + +``` +@interface SourceURL { + public String value(); + public String mail() default ""; +} +``` + +そして以下のように適用します。 + +``` +@SourceURL("http://coders.com/") +public class MyClass extends TheirClass ... +``` + +この場合、Scalaでも同じことができます。 + +``` +@SourceURL("http://coders.com/") +class MyScalaClass ... +``` + +`mail`要素はデフォルト値つきで定義されているので、明示的に値を指定する必要がありません。しかしながら、もし値を指定する必要がある場合、Javaでは2つのスタイルを混ぜて組み合わせることはできません。 + +``` +@SourceURL(value = "http://coders.com/", + mail = "support@coders.com") +public class MyClass extends TheirClass ... +``` + +Scalaはこの点においてより柔軟です。 + +``` +@SourceURL("http://coders.com/", + mail = "support@coders.com") + class MyScalaClass ... +``` diff --git a/_ja/tour/automatic-closures.md b/_ja/tour/automatic-closures.md new file mode 100644 index 0000000000..29ae0a8c00 --- /dev/null +++ b/_ja/tour/automatic-closures.md @@ -0,0 +1,62 @@ +--- +layout: tour +title: Automatic Type-Dependent Closure Construction +language: ja + +discourse: true + +partof: scala-tour +--- + +Scala allows parameterless function names as parameters of methods. When such a method is called, the actual parameters for parameterless function names are not evaluated and a nullary function is passed instead which encapsulates the computation of the corresponding parameter (so-called *call-by-name* evaluation). + +The following code demonstrates this mechanism: + + object TargetTest1 extends Application { + def whileLoop(cond: => Boolean)(body: => Unit): Unit = + if (cond) { + body + whileLoop(cond)(body) + } + var i = 10 + whileLoop (i > 0) { + println(i) + i -= 1 + } + } + +The function whileLoop takes two parameters `cond` and `body`. When the function is applied, the actual parameters do not get evaluated. But whenever the formal parameters are used in the body of `whileLoop`, the implicitly created nullary functions will be evaluated instead. Thus, our method `whileLoop` implements a Java-like while-loop with a recursive implementation scheme. + +We can combine the use of [infix/postfix operators](operators.html) with this mechanism to create more complex statements (with a nice syntax). + +Here is the implementation of a loop-unless statement: + + object TargetTest2 extends Application { + def loop(body: => Unit): LoopUnlessCond = + new LoopUnlessCond(body) + protected class LoopUnlessCond(body: => Unit) { + def unless(cond: => Boolean) { + body + if (!cond) unless(cond) + } + } + var i = 10 + loop { + println("i = " + i) + i -= 1 + } unless (i == 0) + } +The `loop` function just accepts a body of a loop and returns an instance of class `LoopUnlessCond` (which encapsulates this body object). Note that the body didn't get evaluated yet. Class `LoopUnlessCond` has a method `unless` which we can use as a *infix operator*. This way, we achieve a quite natural syntax for our new loop: `loop { < stats > } unless ( < cond > )`. + +Here's the output when `TargetTest2` gets executed: + + i = 10 + i = 9 + i = 8 + i = 7 + i = 6 + i = 5 + i = 4 + i = 3 + i = 2 + i = 1 diff --git a/_ja/tour/basics.md b/_ja/tour/basics.md new file mode 100644 index 0000000000..b14330f2b3 --- /dev/null +++ b/_ja/tour/basics.md @@ -0,0 +1,325 @@ +--- +layout: tour +title: 基本 +language: ja + +discourse: true + +partof: scala-tour + +num: 2 +next-page: unified-types +previous-page: tour-of-scala + +redirect_from: "/tutorials/tour/basics.html" +--- + +このページでは、Scalaの基本を取り扱います。 + +## Scalaをブラウザで試してみる + +ScalaFiddleを利用することでブラウザ上でScalaを実行することができます。 + +1. [https://scalafiddle.io](https://scalafiddle.io)を開きます。 +2. 左側のパネルに`println("Hello, world!")`を貼り付けます。 +3. "Run"ボタンを押すと、右側のパネルに出力が表示されます。 + +このサイトを使えば、簡単にセットアップせずScalaのコードの一部を試すことができます。 + +このドキュメントの多くのコードの例はScalaFiddleで開発されています。 +そのため、サンプルコード内のRunボタンをクリックするだけで、そのまま簡単にコードを試すことができます。 + +## 式 + +式は計算可能な文です。 + +``` +1 + 1 +``` +`println`を使うことで、式の結果を出力できます。 + +{% scalafiddle %} +```tut +println(1) // 1 +println(1 + 1) // 2 +println("Hello!") // Hello! +println("Hello," + " world!") // Hello, world! +``` +{% endscalafiddle %} + +### 値 + +`val`キーワードを利用することで、式の結果に名前を付けることができます。 + +```tut +val x = 1 + 1 +println(x) // 2 +``` + +ここでいうところの `x` のように、名前をつけられた結果は 値 と呼ばれます。 +値を参照した場合、その値は再計算されません。 + +値は再代入することができません。 + +```tut:fail +x = 3 // この記述はコンパイルされません。 +``` + +値の型は推測可能ですが、このように型を明示的に宣言することもできます。 + +```tut +val x: Int = 1 + 1 +``` + +型定義では`Int` は識別子`x`の後にくることに注意してください。そして`:`も必要となります。 + +### 変数 + +再代入ができることを除けば、変数は値と似ています。 +`var`キーワードを使うことで、変数は定義できます。 + +```tut +var x = 1 + 1 +x = 3 // "x"は"var"キーワードで宣言されているので、これはコンパイルされます。 +println(x * x) // 9 +``` + +値と同様に、型を宣言したければ、明示的に型を宣言することができます。 + +```tut +var x: Int = 1 + 1 +``` + + +## ブロック + +`{}`で囲むことで式をまとめることができます。これをブロックと呼びます。 + +ブロックの最後の式の結果はブロック全体の結果にもなります。 + +```tut +println({ + val x = 1 + 1 + x + 1 +}) // 3 +``` + +## 関数 + +関数はパラメーターを受け取る式です。 +ここでは与えられた数値に1を足す無名関数(すなわち名前が無い関数)を宣言しています。 + +```tut +(x: Int) => x + 1 +``` +`=>` の左側はパラメーターのリストです。右側はパラメーターを含む式です。 + +関数には名前をつけることもできます。 + +{% scalafiddle %} +```tut +val addOne = (x: Int) => x + 1 +println(addOne(1)) // 2 +``` +{% endscalafiddle %} + +関数は複数のパラメーターをとることもできます。 + +{% scalafiddle %} +```tut +val add = (x: Int, y: Int) => x + y +println(add(1, 2)) // 3 +``` +{% endscalafiddle %} + +またパラメーターを取らないこともありえます。 + +```tut +val getTheAnswer = () => 42 +println(getTheAnswer()) // 42 +``` + +## メソッド + +メソッドは関数と見た目、振る舞いがとても似ていますが、それらには違いがいくつかあります。 + +メソッドは `def` キーワードで定義されます。 `def` の後ろには名前、パラメーターリスト、戻り値の型、処理の内容が続きます。 + +{% scalafiddle %} +```tut +def add(x: Int, y: Int): Int = x + y +println(add(1, 2)) // 3 +``` +{% endscalafiddle %} + +戻り値の型は引数リストとコロンの「後ろ」に宣言することに注意してください。`: Int` + +メソッドは複数のパラメーターリストを受け取ることができます。 + +{% scalafiddle %} +```tut +def addThenMultiply(x: Int, y: Int)(multiplier: Int): Int = (x + y) * multiplier +println(addThenMultiply(1, 2)(3)) // 9 +``` +{% endscalafiddle %} + +また、パラメーターリストを一切受け取らないこともあります。 + +```tut +def name: String = System.getProperty("user.name") +println("Hello, " + name + "!") +``` +メソッドと関数には他にも違いがありますが、今のところは同じようなものと考えて大丈夫です。 + +メソッドは複数行の式も持つことができます。 +```tut +def getSquareString(input: Double): String = { + val square = input * input + square.toString +} +``` +メソッド本体にある最後の式はメソッドの戻り値になります。(Scalaには`return`キーワードはありますが、めったに使われません。) + +## クラス + +`class` キーワードとその後ろに名前、コンストラクタパラメーターを続けることで、クラスを定義することができます。 + +```tut +class Greeter(prefix: String, suffix: String) { + def greet(name: String): Unit = + println(prefix + name + suffix) +} +``` +`greet` メソッドの戻り値の型は`Unit`です。`Unit`は戻り値として意味がないことを示します。 +それはJavaやC言語の`void`と似たような使われ方をします。(`void`との違いは、全てのScalaの式は値を持つ必要があるため、 +実はUnit型のシングルトンで`()`と書かれる値があります。その値には情報はありません。) + +`new` キーワードを使うことで、クラスのインスタンスを生成することができます。 + +```tut +val greeter = new Greeter("Hello, ", "!") +greeter.greet("Scala developer") // Hello, Scala developer! +``` + +クラスについては[後で](classes.html)詳しく取り扱います。 + +## ケースクラス + +Scalaには"ケース"クラスという特別な種類のクラスがあります。デフォルトでケースクラスは不変であり、値で比較されます。 +`case class` キーワードを利用して、ケースクラスを定義できます。 + +```tut +case class Point(x: Int, y: Int) +``` +ケースクラスは、`new` キーワードなしでインスタンス化できます。 + +```tut +val point = Point(1, 2) +val anotherPoint = Point(1, 2) +val yetAnotherPoint = Point(2, 2) +``` + +ケースクラスは値で比較されます。 + +```tut +if (point == anotherPoint) { + println(point + " and " + anotherPoint + " are the same.") +} else { + println(point + " and " + anotherPoint + " are different.") +} // Point(1,2) と Point(1,2) は同じです。 + +if (point == yetAnotherPoint) { + println(point + " and " + yetAnotherPoint + " are the same.") +} else { + println(point + " and " + yetAnotherPoint + " are different.") +} // Point(1,2) と Point(2,2) は異なります。 +``` + +ケースクラスについて紹介すべきことはたくさんあり、あなたはケースクラスが大好きになると確信しています! +それらについては[後で](case-classes.html)詳しく取り扱います。 + +## オブジェクト + +オブジェクトはそれ自体が定義である単一のインスタンスです。そのクラスのシングルトンと考えることもできます。 + +`object`キーワードを利用してオブジェクトを定義することができます。 + +```tut +object IdFactory { + private var counter = 0 + def create(): Int = { + counter += 1 + counter + } +} +``` + +名前を参照してオブジェクトにアクセスすることができます。 + +```tut +val newId: Int = IdFactory.create() +println(newId) // 1 +val newerId: Int = IdFactory.create() +println(newerId) // 2 +``` + +オブジェクトについては [後で](singleton-objects.html)詳しく取り扱います。 + +## トレイト + +トレイトはいくつかのフィールドとメソッドを含む型です。複数のトレイトを結合することもできます。 + +`trait`キーワードでトレイトを定義することができます。 + +```tut +trait Greeter { + def greet(name: String): Unit +} +``` + +トレイトはデフォルトの実装を持つこともできます。 + +{% scalafiddle %} +```tut +trait Greeter { + def greet(name: String): Unit = + println("Hello, " + name + "!") +} +``` + +`extends`キーワードでトレイトを継承することも、`override` キーワードで実装をオーバーライドすることもできます。 + +```tut +class DefaultGreeter extends Greeter + +class CustomizableGreeter(prefix: String, postfix: String) extends Greeter { + override def greet(name: String): Unit = { + println(prefix + name + postfix) + } +} + +val greeter = new DefaultGreeter() +greeter.greet("Scala developer") // Hello, Scala developer! + +val customGreeter = new CustomizableGreeter("How are you, ", "?") +customGreeter.greet("Scala developer") // How are you, Scala developer? +``` +{% endscalafiddle %} + +ここでは、`DefaultGreeter`は一つのトレイトだけを継承していますが、複数のトレイトを継承することもできます。 + +トレイトについては [後で](traits.html)詳しく取り扱います。 + +## メインメソッド + +メインメソッドはプログラムの始点になります。Javaバーチャルマシーンは`main`と名付けられたメインメソッドが必要で、 +それは文字列の配列を一つ引数として受け取ります。 + +オブジェクトを使い、以下のようにメインメソッドを定義することができます。 + +```tut +object Main { + def main(args: Array[String]): Unit = + println("Hello, Scala developer!") +} +``` diff --git a/_ja/tour/by-name-parameters.md b/_ja/tour/by-name-parameters.md new file mode 100644 index 0000000000..86325795ba --- /dev/null +++ b/_ja/tour/by-name-parameters.md @@ -0,0 +1,45 @@ +--- +layout: tour +title: 名前渡しパラメータ +language: ja + +discourse: true + +partof: scala-tour + +num: 31 +next-page: annotations +previous-page: operators + +redirect_from: "/tutorials/tour/by-name-parameters.html" +--- + +*名前渡しのパラメータ*は使用された時に評価されます。それらは*値渡しパラメータ*とは対照的です。名前渡しのパラメータを作るには、単純に`=>`を型の前につけます。 +```tut +def calculate(input: => Int) = input * 37 +``` + +名前渡しパラメータの利点は関数本体の中で使わなければ評価されない点です。一方で、値渡しパラメータの利点は1度しか評価されない点です。 + +こちらはwhileループをどのように実装するかの例です。 + +```tut +def whileLoop(condition: => Boolean)(body: => Unit): Unit = + if (condition) { + body + whileLoop(condition)(body) + } + +var i = 2 + +whileLoop (i > 0) { + println(i) + i -= 1 +} // prints 2 1 +``` + +このメソッド`whileLoop`は条件とループの本体を受け取るために複数パラメータリストを使います。もし`condition`がtrueならば、`body`が実行され、次にwhileLoopが再帰的に呼ばれます。`condition`がfalseならば、bodyは決して評価されません。それは`body`の型の前に`=>`をつけたからです。 + +ここで、`condition`に`i > 0`、`body`に`println(i); i-= 1`を渡した場合、多くの言語で一般的なwhileループと同じ振る舞いをします。 + +パラメータが使われるまで評価を遅延する機能はパフォーマンスの助けになることがあります。それはパラメータを評価するのに多くの計算が必要な場合や、URLの取得のような時間がかかるコードブロックの場合です。 diff --git a/_ja/tour/case-classes.md b/_ja/tour/case-classes.md new file mode 100644 index 0000000000..99a1b6e6f0 --- /dev/null +++ b/_ja/tour/case-classes.md @@ -0,0 +1,66 @@ +--- +layout: tour +title: ケースクラス +language: ja + +discourse: true + +partof: scala-tour + +num: 11 +next-page: pattern-matching +previous-page: multiple-parameter-lists +prerequisite-knowledge: classes, basics, mutability + +redirect_from: "/tutorials/tour/case-classes.html" +--- + +ケースクラスはこれから論じるいくつかの差異はあるものの普通のクラスと似ています。 +ケースクラスは不変なデータを作るのに適しています。 +このツアーの次のステップでは、[パターンマッチング](pattern-matching.html)でのそれらの有用性を解説します。 + +## ケースクラスの宣言 + +最小のケースクラスにはキーワード`case class`、識別子、パラメータリスト(空かもしれません)が必要です。 +```tut +case class Book(isbn: String) + +val frankenstein = Book("978-0486282114") +``` +ケースクラス`Book`をインスタンス化する時キーワード`new`が使われていないことに気をつけてください。 +これはケースクラスがオブジェクトの生成を行う`apply`メソッドを標準で保有するためです。 + +パラメータ有りでケースクラスを作ると、パラメータはパブリックの`val`となります。 +``` +case class Message(sender: String, recipient: String, body: String) +val message1 = Message("guillaume@quebec.ca", "jorge@catalonia.es", "Ça va ?") + +println(message1.sender) // guillaume@quebec.ca が出力されます +message1.sender = "travis@washington.us" // この行はコンパイルされません +``` +`message1.sender` に再代入することはできません、なぜなら`val`(つまりイミュータブル)だからです。 +ケースクラスでは`var`も使うことができますが、推奨されません。 + +## 比較 +ケースクラスは参照ではなく、構造で比較されます。 +``` +case class Message(sender: String, recipient: String, body: String) + +val message2 = Message("jorge@catalonia.es", "guillaume@quebec.ca", "Com va?") +val message3 = Message("jorge@catalonia.es", "guillaume@quebec.ca", "Com va?") +val messagesAreTheSame = message2 == message3 // true +``` +たとえ`message2`と`message3`が異なるオブジェクトを参照していたとしても、それぞれのオブジェクトの値は等価となります。 + +## コピー +`copy`メソッドを使うことで簡単にケースクラスのインスタンスの(浅い)コピーを作ることができます。 +必要に応じて、コンストラクタ引数を変更することもできます。 +``` +case class Message(sender: String, recipient: String, body: String) +val message4 = Message("julien@bretagne.fr", "travis@washington.us", "Me zo o komz gant ma amezeg") +val message5 = message4.copy(sender = message4.recipient, recipient = "claire@bourgogne.fr") +message5.sender // travis@washington.us +message5.recipient // claire@bourgogne.fr +message5.body // "Me zo o komz gant ma amezeg" +``` +`message4`のrecipientは`message5`のsenderとして使われますが、`message4`の定数`body`は直接コピーされます。 diff --git a/_ja/tour/classes.md b/_ja/tour/classes.md new file mode 100644 index 0000000000..0253f210f5 --- /dev/null +++ b/_ja/tour/classes.md @@ -0,0 +1,131 @@ +--- +layout: tour +title: クラス +language: ja + +discourse: true + +partof: scala-tour + +num: 4 +next-page: traits +previous-page: unified-types +topics: classes +prerequisite-knowledge: no-return-keyword, type-declaration-syntax, string-interpolation, procedures + +redirect_from: "/tutorials/tour/classes.html" +--- + +Scalaにおけるクラスはオブジェクトを作るための設計図です。 +クラスはメソッド、値、変数、型、オブジェクト、トレイト、クラスを持ち、それらはまとめて _メンバー_ と呼ばれます。 +型、オブジェクト、トレイトはツアーで後ほど取り扱います。 + +## クラスを定義する + +最小のクラス定義は単純にキーワード`class`と識別子だけというものです。 +クラス名は大文字から始まるべきです。 + +```tut +class User + +val user1 = new User +``` +`new`キーワードはクラスのインスタンスを作るために使われます。 +`User`はコンストラクターが定義されていないので、引数なしのデフォルトコンストラクターを持ちます。 +しかしながら、コンストラクターとクラス本体は頻繁に欲しくなるでしょう。 +こちらは位置情報のクラス定義の例になります。 + +```tut +class Point(var x: Int, var y: Int) { + + def move(dx: Int, dy: Int): Unit = { + x = x + dx + y = y + dy + } + + override def toString: String = + s"($x, $y)" +} + +val point1 = new Point(2, 3) +point1.x // 2 +println(point1) // prints (2, 3) +``` +この`Point`クラスは4つのメンバーを持ちます。 +変数`x` と `y` そしてメソッド `move` と `toString`です。 +多くの他の言語とは異なり、プライマリコンストラクタはクラスのシグネチャ`(var x: Int, var y: Int)`です。 +`move` メソッドは2つの整数の引数を受け取り、情報を持たない Unit 値 `()` を返します。 +これは大雑把に言えば、Javaのような言語における`void`に対応します。 +その一方で`toString`は引数を受け取りませんが、`String`の値を返します。 +`toString`は[`AnyRef`](unified-types.html)の`toString`をオーバーライドしているので、`override`キーワードのタグが付いています。 + +## コンストラクター + +コンストラクターは次のようにデフォルト値を与えると省略可能なパラメーターを持つことができます。 + +```tut +class Point(var x: Int = 0, var y: Int = 0) + +val origin = new Point // x と y には共に0がセットされます。 +val point1 = new Point(1) +println(point1.x) // 1 が出力されます。 +``` +このバージョンの`Point`クラスでは、`x` と `y` はデフォルト値0を持ち、引数が必須ではありません。 +しかしながらコンストラクタは引数を左から右に読み込むため、もし`y`の値だけを渡したい場合は、パラメーターに名前をつける必要があります。 + +``` +class Point(var x: Int = 0, var y: Int = 0) +val point2 = new Point(y=2) +println(point2.y) // 2 が出力されます。 +``` + +これは明快さを高めるための良い習慣でもあります。 + +## プライベートメンバーとゲッター/セッター構文 +メンバーはデフォルトではパブリックになります。 +クラスの外から隠したい場合は`private`アクセス修飾詞を使いましょう。 + +```tut +class Point { + private var _x = 0 + private var _y = 0 + private val bound = 100 + + def x = _x + def x_= (newValue: Int): Unit = { + if (newValue < bound) _x = newValue else printWarning + } + + def y = _y + def y_= (newValue: Int): Unit = { + if (newValue < bound) _y = newValue else printWarning + } + + private def printWarning = println("WARNING: Out of bounds") +} + +val point1 = new Point +point1.x = 99 +point1.y = 101 // 警告が出力されます。 +``` +このバージョンの`Point`クラスでは、データはプライベート変数 `_x` と `_y` に保存されます。 +プライベートなデータにアクセスするためのメソッド`def x` と `def y` があります。 +`def x_=` と `def y_=` は `_x` と `_y` の値を検証し設定するためのものになります。 +セッターのための特別な構文に注意してください。 +セッターメソッドはゲッターメソッドの識別子に`_=`を追加し、その後ろにパラメーターを取ります。 + +プライマリコンストラクタの`val` と `var` を持つパラメーターはパブリックになります。 +しかしながら`val` は不変となるため、以下のように記述することはできません。 + +``` +class Point(val x: Int, val y: Int) +val point = new Point(1, 2) +point.x = 3 // <-- コンパイルされません。 +``` + +`val` や `var` が存在しないパラメーターはクラス内でだけで参照できるプライベートな値や変数となります。 +``` +class Point(x: Int, y: Int) +val point = new Point(1, 2) +point.x // <-- コンパイルされません。 +``` diff --git a/_ja/tour/compound-types.md b/_ja/tour/compound-types.md new file mode 100644 index 0000000000..6eeadc481d --- /dev/null +++ b/_ja/tour/compound-types.md @@ -0,0 +1,54 @@ +--- +layout: tour +title: 複合型 +language: ja + +discourse: true + +partof: scala-tour + +num: 24 +next-page: self-types +previous-page: abstract-type-members + +redirect_from: "/tutorials/tour/compound-types.html" +--- +ときどき、あるオブジェクトの型が、複数の他の型のサブタイプであると表現する必要が生じます。 +Scalaでは、これは*複合型*を用いて表現できます。複合型とはオブジェクトの型同士を重ねることです。 + +2つのトレイト`Cloneable`と`Resetable`があるとしましょう。 + +```tut +trait Cloneable extends java.lang.Cloneable { + override def clone(): Cloneable = { + super.clone().asInstanceOf[Cloneable] + } +} +trait Resetable { + def reset: Unit +} +``` + +今、関数`cloneAndReset`を書きたいとします。それはオブジェクトを受け取り、それをクローンして、元のオブジェクトをリセットします。 + +``` +def cloneAndReset(obj: ?): Cloneable = { + val cloned = obj.clone() + obj.reset + cloned +} +``` + +パラメータ`obj`の型は何かという疑問が生じます。もし`Cloneable`であれば、オブジェクトを`clone`することができますが、`reset`することはできません。もし`Resetable`であれば、`reset`することができますが、`clone`の操作はできません。そのような状態で型キャストを回避するために`obj`の型を`Cloneable`と`Resetable`の両方であると指定することができます。Scalaではこの複合型は`Cloneable with Resetable`のように書くことができます。 + +こちらが書き変えた関数です。 + +``` +def cloneAndReset(obj: Cloneable with Resetable): Cloneable = { + //... +} +``` +複合型は複数のオブジェクトの型からなり、一つだけの細別型(refinement)を持てます。細別型は既存オブジェクトのメンバーのシグネチャを絞り込むのに使えます。 +一般的な形は`A with B with C ... { refinement }`です。 + +細別の使い方の例は[ミックスインを用いたクラス合成](mixin-class-composition.html)のページにあります。 diff --git a/_ja/tour/default-parameter-values.md b/_ja/tour/default-parameter-values.md new file mode 100644 index 0000000000..fe2da78c75 --- /dev/null +++ b/_ja/tour/default-parameter-values.md @@ -0,0 +1,50 @@ +--- +layout: tour +title: デフォルト引数 +language: ja + +discourse: true + +partof: scala-tour + +num: 33 +next-page: named-arguments +previous-page: annotations +prerequisite-knowledge: named-arguments, function syntax + +redirect_from: "/tutorials/tour/default-parameter-values.html" +--- + +Scalaはパラメータのデフォルト値を与えることができ、呼び出す側はこれらのパラメータを省略できます。 + +```tut +def log(message: String, level: String = "INFO") = println(s"$level: $message") + +log("System starting") // prints INFO: System starting +log("User not found", "WARNING") // prints WARNING: User not found +``` + +パラメータ`level`はデフォルト値を持つので、省略可能です。最終行では、引数`"WARNING"`はデフォルト値`"INFO"`を上書きします。Javaで同じ効果を得るのに、省略可能なパラメータをもつメソッドを複数使ってメソッドのオーバーロードをしたようなものです。しかしながら呼び出す側が引数をひとつ省略すると、以降全ての引数は名前つきにする必要があります。 + +```tut +class Point(val x: Double = 0, val y: Double = 0) + +val point1 = new Point(y = 1) +``` +ここでは、`y = 1`と書かなければなりません。 + +Scalaで定義したデフォルトパラメータはJavaのコードから呼び出される時はオプショナルではありません。 + +```tut +// Point.scala +class Point(val x: Double = 0, val y: Double = 0) +``` + +```java +// Main.java +public class Main { + public static void main(String[] args) { + Point point = new Point(1); // コンパイルされません + } +} +``` diff --git a/_ja/tour/extractor-objects.md b/_ja/tour/extractor-objects.md new file mode 100644 index 0000000000..2b12283764 --- /dev/null +++ b/_ja/tour/extractor-objects.md @@ -0,0 +1,72 @@ +--- +layout: tour +title: 抽出子オブジェクト +language: ja + +discourse: true + +partof: scala-tour + +num: 16 +next-page: for-comprehensions +previous-page: regular-expression-patterns + +redirect_from: "/tutorials/tour/extractor-objects.html" +--- + +抽出子オブジェクトは`unapply`メソッドを持つオブジェクトです。 +`apply`メソッドが引数を取り、オブジェクトを作るコンストラクタであるように、`unapply`は1つのオブジェクトを受け取り、引数を返そうとします。 +これはパターンマッチングと部分関数で最も頻繁に使われます。 + +```tut +import scala.util.Random + +object CustomerID { + + def apply(name: String) = s"$name--${Random.nextLong}" + + def unapply(customerID: String): Option[String] = { + val stringArray: Array[String] = customerID.split("--") + if (stringArray.tail.nonEmpty) Some(stringArray.head) else None + } +} + +val customer1ID = CustomerID("Sukyoung") // Sukyoung--23098234908 +customer1ID match { + case CustomerID(name) => println(name) // prints Sukyoung + case _ => println("Could not extract a CustomerID") +} +``` + +`apply`メソッドは`name`から`CustomerID`文字列を作ります。`unapply`は逆に`name`を返します。 + `CustomerID("Sukyoung")`は、`CustomerID.apply("Sukyoung")`を短く書く構文です。 + `case CustomerID(name) => println(name)`では、unapplyメソッドを呼んでいます。 + +値を定義する文で、パターン中に新しい変数を使うことができるので、抽出子は変数を初期化するのに使えます。この場合unapplyメソッドが初期値を与えます。 + +```tut +val customer2ID = CustomerID("Nico") +val CustomerID(name) = customer2ID +println(name) // prints Nico +``` +これは `val name = CustomerID.unapply(customer2ID).get`.と同じです。 + +```tut +val CustomerID(name2) = "--asdfasdfasdf" +``` +もし一致しない場合`scala.MatchError`が投げられます。 + +```tut:fail +val CustomerID(name3) = "-asdfasdfasdf" +``` + +`unapply`の戻り値型は以下のように選ばれなければなりません。 + +* ただのテストであれば、`Boolean`を返します。例えば`case even()`。 +* T型のサブバリュー1つを返すのであれば、`Option[T]`を返します。 +* いくつかのサブバリュー`T1,...,Tn`を返したいのであれば、オプショナルタプル`Option[(T1,...,Tn)]`でグループ化します。 + +時々、抽出する値の数が確定せず、入力に応じて任意の数の値を返したいことがあります。 +この場合は、`Option[Seq[T]]`を返す`unapplySeq`メソッドを持つ抽出子を定義することができます。 +これらのパターンと同様の例として以下のものがあります。 +`case List(x, y, z) =>`を使って`List`を分解する例や`case r(name, remainingFields @ _*) =>`.のように正規表現`Regex`を使って`String`を分解する例です。 diff --git a/_ja/tour/for-comprehensions.md b/_ja/tour/for-comprehensions.md new file mode 100644 index 0000000000..89bce4d42a --- /dev/null +++ b/_ja/tour/for-comprehensions.md @@ -0,0 +1,77 @@ +--- +layout: tour +title: for内包表記 +language: ja + +discourse: true + +partof: scala-tour + +num: 17 +next-page: generic-classes +previous-page: extractor-objects + +redirect_from: "/tutorials/tour/for-comprehensions.html" +--- + +Scalaは*シーケンス内包表記*を表現するための軽量な記法を提供します。 +内含表記は`for (enumerators) yield e`という形をとります。`enumerators`はセミコロンで区切られたEnumeratorのリストを指します。 +1つの*enumerator*は新しい変数を導き出すジェネレータかフィルタのどちらかです。 +内包表記はenumeratorsが生成する束縛一つ一つについて本体`e`を評価し、これらの値のシーケンスを返します。 + +こちらは例です。 + +```tut +case class User(name: String, age: Int) + +val userBase = List(User("Travis", 28), + User("Kelly", 33), + User("Jennifer", 44), + User("Dennis", 23)) + +val twentySomethings = for (user <- userBase if (user.age >=20 && user.age < 30)) + yield user.name // これをリストに追加する + +twentySomethings.foreach(name => println(name)) // prints Travis Dennis +``` +この`yield`文と一緒に使われている`for`ループは実際には`List`を生成します。 +`yield user.name`を返しているので、型は`List[String]`になります。 +`user <- userBase`はジェネレータであり、`if (user.age >=20 && user.age < 30)`は20代ではないユーザーをフィルターするガードです。 + +こちらは2つのジェネレータを使ったより複雑な例です。 +合計が与えられた値`v`と等しくなる、`0`から`n-1`の全てのペアを計算します。 + +```tut +def foo(n: Int, v: Int) = + for (i <- 0 until n; + j <- 0 until n if i + j == v) + yield (i, j) + +foo(10, 10) foreach { + case (i, j) => + println(s"($i, $j) ") // prints (1, 9) (2, 8) (3, 7) (4, 6) (5, 5) (6, 4) (7, 3) (8, 2) (9, 1) +} + +``` +この例では`n == 10`で`v == 10`です。最初のイテレーションでは`i == 0`かつ`j == 0`で、`i + j != v`となるので、何も生成されません。 +`i`が`1`にインクリメントされるまでに、`j`はあと9回インクリメントされます。`if`ガードがなければ、単純に以下の内容が表示されます。 + +``` + +(0, 0) (0, 1) (0, 2) (0, 3) (0, 4) (0, 5) (0, 6) (0, 7) (0, 8) (0, 9) (1, 0) ... +``` +内包表記はリストだけのものではありません。 +操作 `withFilter`、`map`、`flatMap`を(適切な型で)サポートする全てのデータ型は、シーケンス内包表記で使うことができます。 + +内包表記の中では`yield`を省略することができます。その場合、内包表記は`Unit`を返します。 +これは副作用をもたらす必要があるときに役立ちます。 +こちらは先に出たプログラムと同等のものですが、`yield`を使っていません。 + +```tut +def foo(n: Int, v: Int) = + for (i <- 0 until n; + j <- 0 until n if i + j == v) + println(s"($i, $j)") + +foo(10, 10) +``` diff --git a/_ja/tour/generic-classes.md b/_ja/tour/generic-classes.md new file mode 100644 index 0000000000..2535e31695 --- /dev/null +++ b/_ja/tour/generic-classes.md @@ -0,0 +1,65 @@ +--- +layout: tour +title: ジェネリッククラス +language: ja + +discourse: true + +partof: scala-tour + +num: 18 +next-page: variances +previous-page: for-comprehensions +assumed-knowledge: classes unified-types + +redirect_from: "/tutorials/tour/generic-classes.html" +--- +ジェネリッククラスはパラメータとして型を1つ受け取るクラスです。それらはコレクションクラスで特に役立ちます。 + +## ジェネリッククラスの定義 +ジェネリッククラスは角カッコ`[]`の中にパラメータとして型を1つ受け取ります。 +型パラメータの識別子として文字`A`を使う習慣がありますが、任意のパラメータ名を使うことができます。 +```tut +class Stack[A] { + private var elements: List[A] = Nil + def push(x: A) { elements = x :: elements } + def peek: A = elements.head + def pop(): A = { + val currentTop = peek + elements = elements.tail + currentTop + } +} +``` +この`Stack`クラスの実装はパラメータとして任意の型`A`を受け取ります。 +これはメンバーのリスト`var elements: List[A] = Nil`が型`A`の要素のみを格納できることを意味します。 +手続き`def push`は型`A`のオブジェクトのみを受け取ります +(注: `elements = x :: elements`は、`x`を現在の`elements`の先頭に追加した新しいリストを`elements`に割り当て直します)。 + +## 使い方 + +ジェネリッククラスを使うには、角カッコの中に`A`の代わりに型を入れます。 +``` +val stack = new Stack[Int] +stack.push(1) +stack.push(2) +println(stack.pop) // prints 2 +println(stack.pop) // prints 1 +``` +インスタンス`stack`はIntのみを受け取ることができます。 +しかしながら、型がサブタイプを持つ場合、それらは以下のように渡すことができます。 +``` +class Fruit +class Apple extends Fruit +class Banana extends Fruit + +val stack = new Stack[Fruit] +val apple = new Apple +val banana = new Banana + +stack.push(apple) +stack.push(banana) +``` +クラス`Apple`と`Banana`は共に`Fruit`を継承しています。そのため`Fruit`のスタックには`apple`と`banana`のインスタンスを追加できます。 + +_注意: ジェネリック型のサブタイプは*非変(invariant)*です。つまり`Stack[Char]`型の文字スタックがあるとき、それを`Stack[Int]`型の整数スタックとして使うことはできません。文字スタックに整数を入れることはできるので、このことは変に思えるかもしれません。結論としては、`B = A`の場合に限り、`Stack[A]`は`Stack[B]`の唯一のサブタイプとなります。これでは制限が強いので、ジェネリック型のサブタイプの振る舞いをコントロールするために、Scalaは[型引数アノテーションの仕組み](variances.html)を提供します。_ diff --git a/_ja/tour/higher-order-functions.md b/_ja/tour/higher-order-functions.md new file mode 100644 index 0000000000..57714202e8 --- /dev/null +++ b/_ja/tour/higher-order-functions.md @@ -0,0 +1,121 @@ +--- +layout: tour +title: 高階関数 +language: ja + +discourse: true + +partof: scala-tour + +num: 8 +next-page: nested-functions +previous-page: mixin-class-composition + +redirect_from: "/tutorials/tour/higher-order-functions.html" +--- + +高階関数は他の関数をパラメーターとして受け取る、もしくは結果として関数を返します。 +このようなことができるのは、Scalaでは関数が第一級値 (first-classs value) だからです。 +用語が少し紛らわしいかもしれませんが、 +ここでは"高階関数"というフレーズを関数をパラメーターとして受け取る、または関数を返すメソッドと関数の両方に対して使います。 + +もっとも一般的な例の1つは、Scalaのコレクションで利用可能な高階関数`map`です。 +```tut +val salaries = Seq(20000, 70000, 40000) +val doubleSalary = (x: Int) => x * 2 +val newSalaries = salaries.map(doubleSalary) // List(40000, 140000, 80000) +``` +`doubleSalary`はInt`x`を1つだけ受け取り、`x * 2`を返す関数です。 +一般的に、アロー`=>`の左側のタプルは引数リストであり、右側の式の値が返されます。 +3行目で、給与のリストのそれぞれの値に`doubleSalary`が適用されます。 + +コードを減らすため、以下のように無名関数を作ることができ、引数として直接mapに渡すことができます +``` +val salaries = Seq(20000, 70000, 40000) +val newSalaries = salaries.map(x => x * 2) // List(40000, 140000, 80000) +``` +上記例では`x`をIntとして宣言していないことに注意してください。 +それはmap関数が期待する型を基にコンパイラーが型を推論できるからです。 +さらに言えば、慣用的には同じコードを以下のように書きます。 + +```tut +val salaries = Seq(20000, 70000, 40000) +val newSalaries = salaries.map(_ * 2) +``` +Scalaコンパイラはパラメーターの型を(Intが1つだけと)既に知っているため、関数の右側を提供するだけでよいです。 +唯一の注意点はパラメータ名の代わりに`_`を使う必要があるということです(先の例では`x`でした)。 + +## メソッドを関数に強制変換 +高階関数には引数としてとしてメソッドを渡すことも可能で、それはScalaコンパイラがメソッドを関数に強制変換するからです。 +``` +case class WeeklyWeatherForecast(temperatures: Seq[Double]) { + + private def convertCtoF(temp: Double) = temp * 1.8 + 32 + + def forecastInFahrenheit: Seq[Double] = temperatures.map(convertCtoF) // <-- convertCtoFメソッドが渡されます +} +``` +ここで、メソッド`convertCtoF`が`forecastInFahrenheit`に渡されています。 +これはコンパイラが`convertCtoF`を関数`x => convertCtoF(x)`(注意点:`x`はスコープ内でユニークであることが保証された名前になります)に変換することで実現します。 + +## 関数を受け取る関数 +高階関数を使う理由の1つは余分なコードを削減することです。 +たとえば、何通りかの係数で人の給料を上げるメソッドが欲しいとしましょう。 +高階関数を作らないなら、こんな感じになるかもしれません。 + +```tut +object SalaryRaiser { + + def smallPromotion(salaries: List[Double]): List[Double] = + salaries.map(salary => salary * 1.1) + + def greatPromotion(salaries: List[Double]): List[Double] = + salaries.map(salary => salary * math.log(salary)) + + def hugePromotion(salaries: List[Double]): List[Double] = + salaries.map(salary => salary * salary) +} +``` + +3つのメソッドはそれぞれ掛け算の係数のみ異なることに気をつけてください。 +簡潔にするため、以下のように繰り返されているコードを高階関数に抽出することができます。 + +```tut +object SalaryRaiser { + + private def promotion(salaries: List[Double], promotionFunction: Double => Double): List[Double] = + salaries.map(promotionFunction) + + def smallPromotion(salaries: List[Double]): List[Double] = + promotion(salaries, salary => salary * 1.1) + + def bigPromotion(salaries: List[Double]): List[Double] = + promotion(salaries, salary => salary * math.log(salary)) + + def hugePromotion(salaries: List[Double]): List[Double] = + promotion(salaries, salary => salary * salary) +} +``` +新しいメソッド`promotion`はsalariesと`Double => Double`型の関数(すなわち、Doubleを受け取り、Doubleを返す関数)を受け取り、積を返します。 + +## 関数を返す関数 + +関数を生成したい場合がいくつかあります。 +こちらは関数を返すメソッドの例になります。 + +```tut +def urlBuilder(ssl: Boolean, domainName: String): (String, String) => String = { + val schema = if (ssl) "https://" else "http://" + (endpoint: String, query: String) => s"$schema$domainName/$endpoint?$query" +} + +val domainName = "www.example.com" +def getURL = urlBuilder(ssl=true, domainName) +val endpoint = "users" +val query = "id=1" +val url = getURL(endpoint, query) // "https://www.example.com/users?id=1": String +``` + +urlBuilderの戻り値型`(String, String) => String`に注意してください。 +これは返される無名関数はStringを2つ受け取り、Stringを1つ返すことを意味します。 +このケースでは返される無名関数は`(endpoint: String, query: String) => s"https://www.example.com/$endpoint?$query"`です。 diff --git a/_ja/tour/implicit-conversions.md b/_ja/tour/implicit-conversions.md new file mode 100644 index 0000000000..386ed3c500 --- /dev/null +++ b/_ja/tour/implicit-conversions.md @@ -0,0 +1,62 @@ +--- +layout: tour +title: 暗黙の変換 +language: ja + +discourse: true + +partof: scala-tour + +num: 27 +next-page: polymorphic-methods +previous-page: implicit-parameters + +redirect_from: "/tutorials/tour/implicit-conversions.html" +--- + +型`S`から型`T`への暗黙の変換は`S => T`という型のimplicit値や、その型に一致するimplicitメソッドで定義されます。 + +暗黙の変換は2つの状況で適用されます。 + +* もし式`e`が型`S`であり、`S`は式の期待する型`T`に適合しない場合 +* 型`S`の`e`を使う表記`e.m`があって、セレクター`m`が`S`のメンバーではない場合 + +最初のケースでは、`e`を渡せて、戻り値の型が`T`に適合するような変換`c`を検索します。 +2つ目のケースでは、`e`を渡せて、戻り値が`m`というメンバーを持つような変換`c`を検索します。 + +implicitなメソッド`List[A] => Ordered[List[A]]`と`Int => Ordered[Int]`がスコープの中にあれば、`List[Int]`型の2つのリストにおける以下の処理は正当なものになります。 + +``` +List(1, 2, 3) <= List(4, 5) +``` +implicitなメソッド`Int => Ordered[Int]`は`scala.Predef.intWrapper`を通じて自動的に提供されます。implicitなメソッドの例`List[A] => Ordered[List[A]]`は以下にあります。 + +```tut +import scala.language.implicitConversions + +implicit def list2ordered[A](x: List[A]) + (implicit elem2ordered: A => Ordered[A]): Ordered[List[A]] = + new Ordered[List[A]] { + //replace with a more useful implementation + def compare(that: List[A]): Int = 1 + } +``` +暗黙にインポートされているオブジェクト`scala.Predef`は、頻繁に使われる型(例えば`scala.collection.immutable.Map`は`Map`と別名づけられます)とメソッド(例えば`assert`)といくつかの暗黙の型変換を宣言しています。 + +例えば、`java.lang.Integer`を受け取るようなJavaのメソッドを呼び出す時、自由に`scala.Int`を代わりに渡すことができます。それはPredefオブジェクトが以下の暗黙の変換をを含んでいるからです。 + +```tut +import scala.language.implicitConversions + +implicit def int2Integer(x: Int) = + java.lang.Integer.valueOf(x) +``` + +暗黙の変換は見境なく使われると落とし穴になり得るため、暗黙の変換の定義をコンパイルしている時にコンパイラは警告を出します。 + +警告をオフにするには、次のいずれかの措置を講じてください。 + +* 暗黙の変換定義のスコープに`scala.language.implicitConversions`をインポートする。 +* コンパイラを`-language:implicitConversions`をつけて起動する + +コンパイラにより変換が適用された時、警告は出ません。 diff --git a/_ja/tour/implicit-parameters.md b/_ja/tour/implicit-parameters.md new file mode 100644 index 0000000000..38067f9e27 --- /dev/null +++ b/_ja/tour/implicit-parameters.md @@ -0,0 +1,75 @@ +--- +layout: tour +title: 暗黙のパラメータ +language: ja + +discourse: true + +partof: scala-tour + +num: 26 +next-page: implicit-conversions +previous-page: self-types + +redirect_from: "/tutorials/tour/implicit-parameters.html" +--- + +メソッドは _暗黙の_ パラメータのリストを持つことができ、パラメータリストの先頭には _implicit_ キーワードで印をつけます。 +もしそのパラメータリストの中のパラメータがいつものように渡らなければ、Scalaは正しい型の暗黙値を受け取ることができるかを確認し、可能であればそれを自動的に渡します。 + +Scalaがこれらのパラメータを探す場所は2つのカテゴリに分かれます。 + +* Scalaはまず最初に暗黙のパラメータブロックを持つメソッドが呼び出されている箇所で、直接(プレフィックスなしに)アクセスできる暗黙の定義と暗黙のパラメータを探します。 +* 次に、候補となる型に関連づけられた全てのコンパニオンオブジェクトの中でimplicitと宣言されているメンバーを探します。 + +Scalaがimplicitをどこから見つけるかについてのより詳しいガイドは[FAQ](//docs.scala-lang.org/tutorials/FAQ/finding-implicits.html)で見ることができます。 + +以下の例では、モノイドの`add`と`unit`の演算を使い、要素のリストの合計を計算するメソッド`sum`を定義しています。 +implicitの値をトップレベルには置けないことに注意してください。 + +```tut +abstract class Monoid[A] { + def add(x: A, y: A): A + def unit: A +} + +object ImplicitTest { + implicit val stringMonoid: Monoid[String] = new Monoid[String] { + def add(x: String, y: String): String = x concat y + def unit: String = "" + } + + implicit val intMonoid: Monoid[Int] = new Monoid[Int] { + def add(x: Int, y: Int): Int = x + y + def unit: Int = 0 + } + + def sum[A](xs: List[A])(implicit m: Monoid[A]): A = + if (xs.isEmpty) m.unit + else m.add(xs.head, sum(xs.tail)) + + def main(args: Array[String]): Unit = { + println(sum(List(1, 2, 3))) // intMonoidを暗に使用 + println(sum(List("a", "b", "c"))) // stringMonoidを暗に使用 + } +} +``` +`Monoid`はここでは`add`と呼ばれる処理を定義します。この処理は`A`のペアを結合して、別の`A`を返します。また、(特定の)`A`を作ることができる`unit`と呼ばれる処理も定義します。 + +暗黙のパラメータがどのように働くかを見るため、まずは文字列と整数のためにそれぞれモノイド`stringMonoid`と`intMonoid`を定義します。`implicit`キーワードは対応するオブジェクトが暗黙に使われうることを指し示します。 + +メソッド`sum`は`List[A]`を受け取り、`A`を返します。このメソッドは初期値`A`を`unit`から受け取り、リスト中の`A`を順番に`add`メソッドで結合します。ここでパラメータ`m`をimplicitにしているのは、そのメソッドを呼び出すとき、Scalaが暗黙のパラメータ`m`として暗黙の`Monoid[A]`を見つけることができるなら、私達は`xs`パラメータを提供するだけで良いということです。 + +`main`メソッドでは`sum`を2回呼んでいて、`xs`パラメータだけを渡しています。するとScalaは先に言及したスコープの中でimplicitを探します。最初の`sum`の呼び出しは`xs`として`List[Int]`を渡します。それは `A`が`Int`であることを意味します。暗黙のパラメータリスト`m`が省略されているので、Scalaは暗黙の`Monoid[Int]`を探します。最初の探索ルールはこうでした。 + +> Scalaはまず最初に暗黙のパラメータブロックを持つメソッドが呼び出されている箇所で、直接(プレフィックスなしに)アクセスできる暗黙の定義と暗黙のパラメータを探します。 + +`intMonoid`は`main`の中で直接アクセスできる暗黙の定義です。型も一致しているので、`sum`メソッドに自動的に渡されます。 + +`sum`の2回目の呼び出しは`List[String]`を渡します。それは`A`は`String`であることを意味します。暗黙の値の探索は`Int`の時と同様に動きますが、今回は `stringMonoid`を見つけ、`m`として自動的に渡します。 + +そのプログラムは以下を出力します。 +``` +6 +abc +``` diff --git a/_ja/tour/inner-classes.md b/_ja/tour/inner-classes.md new file mode 100644 index 0000000000..4bc373d8c8 --- /dev/null +++ b/_ja/tour/inner-classes.md @@ -0,0 +1,91 @@ +--- +layout: tour +title: 内部クラス +language: ja + +discourse: true + +partof: scala-tour + +num: 22 +next-page: abstract-type-members +previous-page: lower-type-bounds + +redirect_from: "/tutorials/tour/inner-classes.html" +--- + +Scalaではクラスが他のクラスをメンバーとして保持することが可能です。 +Javaのような、内部クラスが外側のクラスのメンバーとなる言語とは対照的に、Scalaでは、内部クラスは外側のオブジェクトに束縛されます。 +どのノードがどのグラフに属しているのかを私達が混同しないように、コンパイラがコンパイル時に防いでほしいのです。 +パス依存型はその解決策の1つです。 + +その違いを示すために、グラフデータ型の実装をさっと書きます。 + +```tut +class Graph { + class Node { + var connectedNodes: List[Node] = Nil + def connectTo(node: Node) { + if (connectedNodes.find(node.equals).isEmpty) { + connectedNodes = node :: connectedNodes + } + } + } + var nodes: List[Node] = Nil + def newNode: Node = { + val res = new Node + nodes = res :: nodes + res + } +} +``` +このプログラムはグラフをノードのリスト(`List[Node]`)で表現しています。いずれのノードも接続している他のノードへのリスト(`connectedNodes`)を保持します。`class Node`は `class Graph`の中にネストしているので、 _パス依存型_ です。 +そのため`connectedNodes`の中にある全てのノードは同じ`Graph`インスタンスから`newNode`を使用して作る必要があります。 + +```tut +val graph1: Graph = new Graph +val node1: graph1.Node = graph1.newNode +val node2: graph1.Node = graph1.newNode +val node3: graph1.Node = graph1.newNode +node1.connectTo(node2) +node3.connectTo(node1) +``` +わかりやすくするため`node1`、`node2`、`node3`の型を`graph1.Node`と明示的に宣言しましたが、なくてもコンパイラは推論できます。 +これは`new Node`を呼んでいる`graph1.newNode`を呼び出す時、メソッドが`Node`のインスタンス`graph1`を使用しているからです。 + +2つのグラフがあるとき、Scalaの型システムは1つのグラフの中で定義されたノードと別のグラフで定義されたノードを混ぜることを許しません。 +それは別のグラフのノードは別の型を持つからです。 +こちらは不正なプログラムです。 + +``` +val graph1: Graph = new Graph +val node1: graph1.Node = graph1.newNode +val node2: graph1.Node = graph1.newNode +node1.connectTo(node2) // legal +val graph2: Graph = new Graph +val node3: graph2.Node = graph2.newNode +node1.connectTo(node3) // illegal! +``` +型`graph1.Node`は`graph2.Node`とは異なります。Javaであれば先のプログラム例の最後の行は正しいでしょう。 +2つのグラフのノードに対して、Javaは同じ型`Graph.Node`を指定します。つまりクラス`Graph`は`Node`の接頭辞です。 +Scalaではそのような型も同様に表現することができ、`Graph#Node`と書きます。 +もし他のグラフのノードに接続できるようにしたければ、以下の方法で最初のグラフ実装の定義を変える必要があります。 + +```tut +class Graph { + class Node { + var connectedNodes: List[Graph#Node] = Nil + def connectTo(node: Graph#Node) { + if (connectedNodes.find(node.equals).isEmpty) { + connectedNodes = node :: connectedNodes + } + } + } + var nodes: List[Node] = Nil + def newNode: Node = { + val res = new Node + nodes = res :: nodes + res + } +} +``` diff --git a/_ja/tour/lower-type-bounds.md b/_ja/tour/lower-type-bounds.md new file mode 100644 index 0000000000..d461e31e5d --- /dev/null +++ b/_ja/tour/lower-type-bounds.md @@ -0,0 +1,76 @@ +--- +layout: tour +title: 下限型境界 +language: ja + +discourse: true + +partof: scala-tour + +num: 21 +next-page: inner-classes +previous-page: upper-type-bounds +prerequisite-knowledge: upper-type-bounds, generics, variance + +redirect_from: "/tutorials/tour/lower-type-bounds.html" +--- + + [上限型境界](upper-type-bounds.html) は型を別の型のサブタイプに制限しますが、*下限型境界*は型が別の型のスーパータイプであることを宣言します。表現`B >: A`はパラメータ`B`または抽象型`B`が型`A`のスーパータイプであることを表します。ほとんどのケースで`A`はそのクラスの型パラメータであり、`B`はメソッドの型パラメータになります。 + +以下はこれが役立つ場合の例です。 + +```tut:fail +trait Node[+B] { + def prepend(elem: B): Node[B] +} + +case class ListNode[+B](h: B, t: Node[B]) extends Node[B] { + def prepend(elem: B): ListNode[B] = ListNode(elem, this) + def head: B = h + def tail: Node[B] = t +} + +case class Nil[+B]() extends Node[B] { + def prepend(elem: B): ListNode[B] = ListNode(elem, this) +} +``` + +このプログラムは片方向リストを実装します。`Nil`は空の要素(すなわち空のリスト)を意味します。 +`class ListNode`は型`B` (`head`)の要素と、リストの残りの部分(`tail`)への参照を持つノードです。 +`class Node`とそのサブタイプは、`+B`とあるので、共変です。 + +しかしながら、このプログラムはコンパイル _されません_。`prepend`のパラメータ`elem`が、宣言時に*共* 変と宣言した型`B`になっているからです。 +なぜ通らないかというと、関数はそれらの型パラメータに対して*反*変であり、それらの結果型に対して*共*変だからです。 + +これを解決するためには、`prepend`のパラメータ`elem`の型の変位指定を逆転させる必要があります。 +これを実現するには、下限型境界として`B`を持つ新しい型パラメータ`U`を導入します。 + +```tut +trait Node[+B] { + def prepend[U >: B](elem: U): Node[U] +} + +case class ListNode[+B](h: B, t: Node[B]) extends Node[B] { + def prepend[U >: B](elem: U): ListNode[U] = ListNode(elem, this) + def head: B = h + def tail: Node[B] = t +} + +case class Nil[+B]() extends Node[B] { + def prepend[U >: B](elem: U): ListNode[U] = ListNode(elem, this) +} +``` + +すると、以下のようなことができます。 +```tut +trait Bird +case class AfricanSwallow() extends Bird +case class EuropeanSwallow() extends Bird + + +val africanSwallowList= ListNode[AfricanSwallow](AfricanSwallow(), Nil()) +val birdList: Node[Bird] = africanSwallowList +birdList.prepend(new EuropeanSwallow) +``` +`Node[Bird]`は`africanSwallowList`をアサインできますが、その後`EuropeanSwallow`を受け入れられます。 + diff --git a/_ja/tour/mixin-class-composition.md b/_ja/tour/mixin-class-composition.md new file mode 100644 index 0000000000..9ec9fd65f4 --- /dev/null +++ b/_ja/tour/mixin-class-composition.md @@ -0,0 +1,84 @@ +--- +layout: tour +title: ミックスインを用いたクラス合成 +language: ja + +discourse: true + +partof: scala-tour + +num: 7 +next-page: higher-order-functions +previous-page: tuples +prerequisite-knowledge: inheritance, traits, abstract-classes, unified-types + +redirect_from: "/tutorials/tour/mixin-class-composition.html" +--- +ミックスインはクラスを構成するのに使われるトレイトです。 + +```tut +abstract class A { + val message: String +} +class B extends A { + val message = "I'm an instance of class B" +} +trait C extends A { + def loudMessage = message.toUpperCase() +} +class D extends B with C + +val d = new D +println(d.message) // I'm an instance of class B +println(d.loudMessage) // I'M AN INSTANCE OF CLASS B +``` +クラス`D`は スーパークラスを`B` とし、 ミックスイン`C`を持ちます。 +クラスは1つだけしかスーパークラスを持つことができませんが、ミックスインは複数持つことができます(キーワードはそれぞれ`extends`と`with`を使います)。 +ミックスインとスーパークラスは同じスーパータイプを持つことができます。 + +それでは抽象クラスから始まる興味深い例を見てみましょう。 + +```tut +abstract class AbsIterator { + type T + def hasNext: Boolean + def next(): T +} +``` +クラスは抽象型`T`と標準的なイテレーターのメソッドを持ちます。 +次に、(全ての抽象メンバー`T`, `hasNext`, `next`が実装を持つ)具象クラスを実装します。 + +```tut +class StringIterator(s: String) extends AbsIterator { + type T = Char + private var i = 0 + def hasNext = i < s.length + def next() = { + val ch = s charAt i + i += 1 + ch + } +} +``` +`StringIterator`は`String`を受け取り、そのStringを反復処理するために使われます。 +(例:Stringに特定の文字が含まれているかを確認するために) + +それでは`AbsIterator`を継承したトレイトも作ってみましょう。 + +```tut +trait RichIterator extends AbsIterator { + def foreach(f: T => Unit): Unit = while (hasNext) f(next()) +} +``` +このトレイトは(`while (hasNext)`で)要素がある限り、与えられた関数 `f: T => Unit`を次の要素(`next()`)に対し連続して呼び出す`foreach`メソッドを実装しています。 +`RichIterator`はトレイトなので、`RichIterator`はAbsIteratorの抽象メンバーを実装する必要がありません。 + +`StringIterator`と`RichIterator`の機能を1つのクラスに組み合わせてみましょう。 +```tut +class RichStringIter extends StringIterator("Scala") with RichIterator +val richStringIter = new RichStringIter +richStringIter foreach println +``` +新しいクラス`RichStringIter`は`StringIterator`をスーパークラスとし、`RichIterator`をミックスインとしています。 + +単一継承ではこのレベルの柔軟性を達成することはできないでしょう。 diff --git a/_ja/tour/multiple-parameter-lists.md b/_ja/tour/multiple-parameter-lists.md new file mode 100644 index 0000000000..a35bccf615 --- /dev/null +++ b/_ja/tour/multiple-parameter-lists.md @@ -0,0 +1,79 @@ +--- +layout: tour +title: 複数パラメータリスト(カリー化) +language: ja + +discourse: true + +partof: scala-tour + +num: 10 +next-page: case-classes +previous-page: nested-functions + +redirect_from: "/tutorials/tour/multiple-parameter-lists.html" +--- + +メソッドは複数のパラメータリストを持てます。 + +# 例 + +こちらはScalaのコレクションAPIの `TraversableOnce`トレイトで定義されている実例です。 + +``` +def foldLeft[B](z: B)(op: (B, A) => B): B +``` +`foldLeft`は、2つのパラメータを取る関数`op`を、初期値`z`とこのコレクションの全要素に対して左から右に適用していきます。 +以下はその使い方の例です。 + +初期値0から始まり、`foldLeft`はここではリスト内の各要素とその一つ前の累積値に関数`(m, n) => m + n`を適用します。 + +{% scalafiddle %} +```tut +val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) +val res = numbers.foldLeft(0)((m, n) => m + n) +println(res) // 55 +``` +{% endscalafiddle %} + +### ユースケース +推奨される複数パラメータリストのユースケースは次の通りです。 + +#### パラメータに関数を一つ渡す場合 +パラメータに関数を一つだけ渡すのであれば、上記の`foldLeft`のケースでの`op`のように、複数パラメータリストを利用して簡潔な構文でメソッドに無名関数を渡すことができます。 +複数パラメータリストがない場合、このコードは以下のようになります。 + + +``` +numbers.foldLeft(0, (m: Int, n: Int) => m + n) +``` + +複数パラメータリストを使うことで、Scalaの型インターフェースの利点を享受でき、以下のようにコードをより簡潔にすることができるのです。 + +``` +numbers.foldLeft(0)(_ + _) +``` +単一のパラメータリストではScalaコンパイラが関数のパラメータを型推論できないので、このようなことはできません。 + +#### 暗黙のパラメータ +特定のパラメータだけを`implicit`として指定するには、`implicit`のパラメーターリストに入れなければなりません。 +こちらが例です。 + +``` +def execute(arg: Int)(implicit ec: scala.concurrent.ExecutionContext) = ??? +``` + +#### 部分適用 + +メソッドが少ない数のパラメータリストで呼び出された時、不足しているパラメータリストを引数として受け取る関数が生成されます。 +これは一般的に[部分適用](https://en.wikipedia.org/wiki/Partial_application)として知られています。 + +例えば +```tut +val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) +val numberFunc = numbers.foldLeft(List[Int]()) _ +val squares = numberFunc((xs, x) => xs :+ x*x) +print(squares) // List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100) +val cubes = numberFunc((xs, x) => xs :+ x*x*x) +print(cubes) // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000) +``` diff --git a/_ja/tour/named-arguments.md b/_ja/tour/named-arguments.md new file mode 100644 index 0000000000..b7f0ca82a2 --- /dev/null +++ b/_ja/tour/named-arguments.md @@ -0,0 +1,36 @@ +--- +layout: tour +title: 名前付き引数 +language: ja + +discourse: true + +partof: scala-tour + +num: 34 +next-page: packages-and-imports +previous-page: default-parameter-values +prerequisite-knowledge: function-syntax + +redirect_from: "/tutorials/tour/named-arguments.html" +--- + +メソッドを呼ぶ時、以下のように引数にパラメータ名でラベル付が可能です。 + +```tut +def printName(first: String, last: String): Unit = { + println(first + " " + last) +} + +printName("John", "Smith") // Prints "John Smith" +printName(first = "John", last = "Smith") // Prints "John Smith" +printName(last = "Smith", first = "John") // Prints "John Smith" +``` + +名前付き引数の順序はどのように並び替えられるかに気をつけましょう。ただし、名前つき引数と名前つきでない引数がある場合は、名前つきでない引数は引数リストの最初に置かれ、かつメソッドシグネチャのパラメーター順でなければなりません。 + +```tut:fail +printName(last = "Smith", "john") // error: positional after named argument +``` + +名前付き引数はJavaメソッドを呼び出す時には使えません。 diff --git a/_ja/tour/nested-functions.md b/_ja/tour/nested-functions.md new file mode 100644 index 0000000000..05a57a2fae --- /dev/null +++ b/_ja/tour/nested-functions.md @@ -0,0 +1,40 @@ +--- +layout: tour +title: ネストしたメソッド +language: ja + +discourse: true + +partof: scala-tour + +num: 9 +next-page: multiple-parameter-lists +previous-page: higher-order-functions + +redirect_from: "/tutorials/tour/nested-functions.html" +--- + +Scalaではメソッドの定義をネストする(_訳注:入れ子にする_)ことができます。 +以下のコードは与えられた数値の階乗を計算するための`factorial`メソッドを提供します。 + +{% scalafiddle %} +```tut + def factorial(x: Int): Int = { + def fact(x: Int, accumulator: Int): Int = { + if (x <= 1) accumulator + else fact(x - 1, x * accumulator) + } + fact(x, 1) + } + + println("Factorial of 2: " + factorial(2)) + println("Factorial of 3: " + factorial(3)) +``` +{% endscalafiddle %} + +このプログラムの出力は以下の通りです。 + +``` +Factorial of 2: 2 +Factorial of 3: 6 +``` diff --git a/_ja/tour/operators.md b/_ja/tour/operators.md new file mode 100644 index 0000000000..b61b229558 --- /dev/null +++ b/_ja/tour/operators.md @@ -0,0 +1,88 @@ +--- +layout: tour +title: 演算子 +language: ja + +discourse: true + +partof: scala-tour + +num: 30 +next-page: by-name-parameters +previous-page: type-inference +prerequisite-knowledge: case-classes + +redirect_from: "/tutorials/tour/operators.html" +--- +Scalaでは演算子はメソッドです。パラメータを1つだけ持つメソッドであれば*中置演算子*として使えます。例えば、`+`はドット記法で呼び出せます。 + +``` +10.+(1) +``` + +しかしながら、中置演算子の方が読みやすいです。 + +``` +10 + 1 +``` + +## 演算子の定義方法と使い方 + +有効な識別子であれば演算子として使用できます。これは `add`のような名前も`+`のような記号も含みます。 +```tut +case class Vec(val x: Double, val y: Double) { + def +(that: Vec) = new Vec(this.x + that.x, this.y + that.y) +} + +val vector1 = Vec(1.0, 1.0) +val vector2 = Vec(2.0, 2.0) + +val vector3 = vector1 + vector2 +vector3.x // 3.0 +vector3.y // 3.0 +``` +クラスVecはメソッド`+`を持ち、 `vector1`と`vector2`を足しわせるのに使います。丸括弧を用いて、複雑な式を読みやすい構文で作ることができます。 +こちらはクラス`MyBool`の定義です。クラス`MyBool`はメソッド`and`と`or`を含みます。 + +```tut +case class MyBool(x: Boolean) { + def and(that: MyBool): MyBool = if (x) that else this + def or(that: MyBool): MyBool = if (x) this else that + def negate: MyBool = MyBool(!x) +} +``` + +この時、`and`と`or`を中置演算子として使えます。 + +```tut +def not(x: MyBool) = x.negate +def xor(x: MyBool, y: MyBool) = (x or y) and not(x and y) +``` + +これにより`xor`の定義がより読みやすくなります。 + +## 優先順位 + +式が複数の演算子を使う時、それらの演算子は最初の文字の(以下に挙げる)優先度に基づき評価されます。 +``` +(以下に表示されていない記号) +* / % ++ - +: += ! +< > +& +^ +| +(全ての文字) +``` +これはあなたが定義した関数にも適用できます。 +たとえば、以下の式 +``` +a + b ^? c ?^ d less a ==> b | c +``` +は以下と同じ意味です。 +``` +((a + b) ^? (c ?^ d)) less ((a ==> b) | c) +``` +`?^`は最も高い優先順位を持ちます。`?^`は`?`から始まるからです。`+`は二番目に高い優先順位を持ち、その後に`==>`、 `^?`、 `|`、 そして`less`が続きます。 diff --git a/_ja/tour/package-objects.md b/_ja/tour/package-objects.md new file mode 100644 index 0000000000..fd7eaced57 --- /dev/null +++ b/_ja/tour/package-objects.md @@ -0,0 +1,73 @@ +--- +layout: tour +title: パッケージオブジェクト +language: ja + +discourse: true + +partof: scala-tour + +num: 36 +previous-page: packages-and-imports +--- + +# パッケージオブジェクト + +Scalaはパッケージ全体を通して共有される便利なコンテナとしてパッケージオブジェクトを提供します。 + +パッケージオブジェクトは、変数やメソッド定義だけでなく、任意の定義を含むことができます。 +例えば、それらはパッケージ全体で使われる型エイリアスと暗黙の変換を保有するためによく使われます。 +パッケージオブジェクトはScalaクラスやトレイトを継承することもできます。 + +慣習として、パッケージオブジェクトのソースコードは通常`package.scala`という名のソースファイルに設置されます。 + +1つのパッケージはパッケージオブジェクトを1つ持てます。パッケージオブジェクト内の全ての定義はパッケージ自体のメンバーと見なされます。 + +以下の例を見てみましょう。まず1つのクラス`Fruit`と3つの`Fruit`オブジェクトがパッケージ`gardening.fruits`にあるとします。 + +``` +// ファイル gardening/fruits/Fruit.scala の中 +package gardening.fruits + +case class Fruit(name: String, color: String) +object Apple extends Fruit("Apple", "green") +object Plum extends Fruit("Plum", "blue") +object Banana extends Fruit("Banana", "yellow") +``` + +ここで、変数`planted`とメソッド`showFruit`を直接パッケージ`gardening.fruits`内に置きたいとします。 +こちらがその方法になります。 + +``` +// ファイル gardening/fruits/package.scala の中 +package gardening +package object fruits { + val planted = List(Apple, Plum, Banana) + def showFruit(fruit: Fruit): Unit = { + println(s"${fruit.name}s are ${fruit.color}") + } +} +``` + +利用側がどのようになるかの例としては、以下のオブジェクト`PrintPlanted`は、ワイルドカードインポートでクラス`Fruit`と全く同様に`planted`と`showFruit`をインポートしています。 + +``` +// ファイル PrintPlanted.scala の中 +import gardening.fruits._ +object PrintPlanted { + def main(args: Array[String]): Unit = { + for (fruit <- fruits.planted) { + showFruit(fruit) + } + } +} +``` + +パッケージオブジェクトは他のオブジェクトのように、継承を利用して構成できます。例えば、一つのパッケージオブジェクトが2つのトレイトをミックスインしている例を示します。 + +``` +package object fruits extends FruitAliases with FruitHelpers { + // ヘルパーと変数がここに続きます。 +} +``` +メソッドオーバーライドはパッケージオブジェクト内では動作しないので気をつけましょう。 diff --git a/_ja/tour/packages-and-imports.md b/_ja/tour/packages-and-imports.md new file mode 100644 index 0000000000..dd2e42f844 --- /dev/null +++ b/_ja/tour/packages-and-imports.md @@ -0,0 +1,87 @@ +--- +layout: tour +title: パッケージとインポート +language: ja + +discourse: true + +partof: scala-tour + +num: 35 +previous-page: named-arguments +next-page: package-objects +--- + +# パッケージとインポート +Scalaは名前空間を作るためにパッケージを使います。名前空間によりプログラムをモジュール化できます。 + +## パッケージの作成 +Scalaファイルの先頭で1つ以上のパッケージ名を宣言することでパッケージは作られます。 + +``` +package users + +class User +``` +パッケージとScalaファイルが含まれるディレクトリは同じ名前をつける習慣があります。しかし、Scalaはファイルのレイアウトには関知しません。`package users`を含むsbtプロジェクトのディレクトリ構成はこのようになるかもしれません。 + +``` +- ExampleProject + - build.sbt + - project + - src + - main + - scala + - users + User.scala + UserProfile.scala + UserPreferences.scala + - test +``` +`users`ディレクトリがどのように`scala`ディレクトリの中にあり、複数のScalaファイルがどのようにパッケージ内にあるのかに注意してください。パッケージ内のScalaファイルは同じパッケージ宣言を持ちます。パッケージ宣言の他の方法は波括弧を使い以下のようにします。 + +``` +package users { + package administrators { + class NormalUser + } + package normalusers { + class NormalUser + } +} +``` +見ての通り、この方法はパッケージのネストができ、スコープとカプセル化をより強くコントロールできます。 + +パッケージ名は全て小文字で書き、もしコードがwebサイトを持つ組織によって開発される場合、慣習として次のフォーマットであるべきです。`<トップレベルドメイン>.<ドメイン名>.<プロジェクト名>`。例えば、Googleが`SelfDrivingCar`と呼ばれるプロジェクトを持っている場合、パッケージ名はこんな風になるでしょう。 +``` +package com.google.selfdrivingcar.camera + +class Lens +``` +これは次のディレクトリ構成に対応します。`SelfDrivingCar/src/main/scala/com/google/selfdrivingcar/camera/Lens.scala` + +## インポート +`import`句は他パッケージのメンバー(クラス、トレイト、関数など)にアクセスするためのものです。同じパッケージのメンバーにアクセスするには`import`句は必要ありません。import句は以下のどれでも使えます。 +``` +import users._ // usersパッケージから全てをインポートする +import users.User // クラスUserをインポートする +import users.{User, UserPreferences} // 選択されたメンバーのみインポートする +import users.{UserPreferences => UPrefs} // インポートし利便性のために名前を変更する +``` +ScalaのJavaと異なる点の1つはインポートがどこでも使える点です。 + +```tut +def sqrtplus1(x: Int) = { + import scala.math.sqrt + sqrt(x) + 1.0 +} +``` +名前競合があり、プロジェクトのルートから何かをインポートする必要がある時、パッケージ名の前に`_root_`をつけます。 +``` +package accounts + +import _root_.users._ +``` + + +注:`scala`と`java.lang` パッケージは`object Predef`と同じように標準でインポートされています。 diff --git a/_ja/tour/pattern-matching.md b/_ja/tour/pattern-matching.md new file mode 100644 index 0000000000..d44d13e41b --- /dev/null +++ b/_ja/tour/pattern-matching.md @@ -0,0 +1,166 @@ +--- +layout: tour +title: パターンマッチング +language: ja + +discourse: true + +partof: scala-tour + +num: 12 + +next-page: singleton-objects +previous-page: case-classes +prerequisite-knowledge: case-classes, string-interpolation, subtyping + +redirect_from: "/tutorials/tour/pattern-matching.html" +--- + +パターンマッチングは値をパターンに照合するための仕組みです。 +マッチに成功すれば、一つの値をその構成要素のパーツに分解することもできます。 +Javaの`switch`文の強化バージョンで、if/else文の連続の代わりとして同様に使うことができます。 + +## 構文 + +マッチ式は値、キーワード`match`と少なくとも1つの`case`句を持ちます。 +```tut +import scala.util.Random + +val x: Int = Random.nextInt(10) + +x match { + case 0 => "zero" + case 1 => "one" + case 2 => "two" + case _ => "other" +} +``` +上記の`val x`は0から10の間のランダムな整数です。`x`は`match`演算子の左オペランドで、右側は4つのケースを持つ式です。 +最後のケース`_`は その他の取りうる整数値のための"全てを捕捉する"ケースです。 +ケースは*オルタナティブ*とも呼ばれます。 + +マッチ式は値を持ちます。 +```tut +def matchTest(x: Int): String = x match { + case 1 => "one" + case 2 => "two" + case _ => "other" +} +matchTest(3) // other +matchTest(1) // one +``` +全てのケースでStringを返しているので、このマッチ式はString型を持ちます。 +そのため関数`matchTest`はStringを返します。 + +## ケースクラスでのマッチング + +ケースクラスはパターンマッチングで特に役立ちます。 + +```tut +abstract class Notification + +case class Email(sender: String, title: String, body: String) extends Notification + +case class SMS(caller: String, message: String) extends Notification + +case class VoiceRecording(contactName: String, link: String) extends Notification + +``` +`Notification`は抽象スーパークラスで、ケースクラスの実装`Email`、 `SMS`、 `VoiceRecording`3つの具象クラスがあります。 +今、これらのケースクラスでパターンマッチングをすることができます。 + +``` +def showNotification(notification: Notification): String = { + notification match { + case Email(sender, title, _) => + s"You got an email from $sender with title: $title" + case SMS(number, message) => + s"You got an SMS from $number! Message: $message" + case VoiceRecording(name, link) => + s"you received a Voice Recording from $name! Click the link to hear it: $link" + } +} +val someSms = SMS("12345", "Are you there?") +val someVoiceRecording = VoiceRecording("Tom", "voicerecording.org/id/123") + +println(showNotification(someSms)) // You got an SMS from 12345! Message: Are you there? が出力されます。 + +println(showNotification(someVoiceRecording)) // you received a Voice Recording from Tom! Click the link to hear it: voicerecording.org/id/123 が出力されます。 +``` +関数`showNotification`は抽象型`Notification`をパラメータとして受け取り、`Notification`の型でマッチします(すなわち`Email`、`SMS`、または `VoiceRecording`のいずれであるかを解決します)。 +`case Email(sender, title, _)` ではフィールド`sender`と`title`が戻り値として使われますが、`_`を使うことでフィールド`body`は無視されます。 + +## パターンガード +パターンガードはケースをより具体的にするために使われる簡単な真偽表現です。 +`if `をパターンの後ろに追加するだけです。 + +``` + +def showImportantNotification(notification: Notification, importantPeopleInfo: Seq[String]): String = { + notification match { + case Email(sender, _, _) if importantPeopleInfo.contains(sender) => + "You got an email from special someone!" + case SMS(number, _) if importantPeopleInfo.contains(number) => + "You got an SMS from special someone!" + case other => + showNotification(other) // 特別なものではなく、オリジナルのshowNotification関数に委譲します。 + } +} + +val importantPeopleInfo = Seq("867-5309", "jenny@gmail.com") + +val someSms = SMS("867-5309", "Are you there?") +val someVoiceRecording = VoiceRecording("Tom", "voicerecording.org/id/123") +val importantEmail = Email("jenny@gmail.com", "Drinks tonight?", "I'm free after 5!") +val importantSms = SMS("867-5309", "I'm here! Where are you?") + +println(showImportantNotification(someSms, importantPeopleInfo)) +println(showImportantNotification(someVoiceRecording, importantPeopleInfo)) +println(showImportantNotification(importantEmail, importantPeopleInfo)) +println(showImportantNotification(importantSms, importantPeopleInfo)) +``` + +`case Email(sender, _, _) if importantPeopleInfo.contains(sender)`では、パターンは`sender`が重要な人のリストに存在して初めてマッチします。 + +## 型のみでのマッチング + +以下のように型のみでマッチすることができます。 +```tut +abstract class Device +case class Phone(model: String) extends Device{ + def screenOff = "Turning screen off" +} +case class Computer(model: String) extends Device { + def screenSaverOn = "Turning screen saver on..." +} + +def goIdle(device: Device) = device match { + case p: Phone => p.screenOff + case c: Computer => c.screenSaverOn +} +``` +`def goIdle`は`Device`の型によって異なる振る舞いをします。 +これはケースがそのパターンのメソッドを呼び出す必要がある時に役立ちます。 +ケースの識別子には型の最初の一文字(この場合に`p`と`c`)を利用する慣習があります。 + +## シールドクラス +トレイトとクラスに`sealed`をつけると、全てのサブタイプは同一ファイル内で宣言されなければならないという意味になります。 +これは全てのサブタイプが既知であることを保証します。 + +```tut +sealed abstract class Furniture +case class Couch() extends Furniture +case class Chair() extends Furniture + +def findPlaceToSit(piece: Furniture): String = piece match { + case a: Couch => "Lie on the couch" + case b: Chair => "Sit on the chair" +} +``` +これは"全てに対応する"ケースを必要としなくて済むので、パターンマッチングで役立ちます。 + +## 注意 +Scalaのパターンマッチング文は[ケースクラス](case-classes.html)で表現される代数型のマッチングに最も役立ちます。 + + +Scalaでは[抽出子オブジェクト](extractor-objects.html)の`unapply`メソッドを使うと、ケースクラスのパターンを独自に定義することもできます。 diff --git a/_ja/tour/polymorphic-methods.md b/_ja/tour/polymorphic-methods.md new file mode 100644 index 0000000000..0770657246 --- /dev/null +++ b/_ja/tour/polymorphic-methods.md @@ -0,0 +1,39 @@ +--- +layout: tour +title: ポリモーフィックメソッド +language: ja + +discourse: true + +partof: scala-tour + +num: 28 + +next-page: type-inference +previous-page: implicit-conversions +prerequisite-knowledge: unified-types + +redirect_from: "/tutorials/tour/polymorphic-methods.html" +--- + +Scalaのメソッドは値と同様に型によってパラメータ化することができます。構文はジェネリッククラスの構文と似ています。 +値パラメータは丸括弧で囲まれるのに対して、型パラメータは角カッコで囲まれます。 + +こちらが例です。 + +```tut +def listOfDuplicates[A](x: A, length: Int): List[A] = { + if (length < 1) + Nil + else + x :: listOfDuplicates(x, length - 1) +} +println(listOfDuplicates[Int](3, 4)) // List(3, 3, 3, 3) +println(listOfDuplicates("La", 8)) // List(La, La, La, La, La, La, La, La) +``` + +メソッド`listOfDuplicates`は型パラメータ`A`と値パラメータ`x`と`length`を受け取ります。値`x`の型は`A`です。もし`length < 1`なら空のリストを返します。それ以外の場合は`x`を再帰呼び出しで返された複写リストの先頭に追加します。(`::`の意味は、左辺の要素を右辺のリストの先頭に追加することです。) + +最初の呼び出し例では、`[Int]`と書いて明示的に型引数を渡しています。そのため最初の引数は`Int`でなければならず、戻される型は`List[Int]`となります。 + +2つ目の呼び出し例では必ずしも明示的に型パラメータを渡す必要がないことを示しています。コンパイラは文脈または値引数の型に基づき、型パラメータを推論できることが多いです。この例では`"La"`が`String`なので、コンパイラは`A`が`String`に違いないことが分かります。 diff --git a/_ja/tour/regular-expression-patterns.md b/_ja/tour/regular-expression-patterns.md new file mode 100644 index 0000000000..21068d1de1 --- /dev/null +++ b/_ja/tour/regular-expression-patterns.md @@ -0,0 +1,63 @@ +--- +layout: tour +title: 正規表現パターン +language: ja + +discourse: true + +partof: scala-tour + +num: 15 + +next-page: extractor-objects +previous-page: singleton-objects + +redirect_from: "/tutorials/tour/regular-expression-patterns.html" +--- +正規表現はデータの中からパターン(またはその欠如)を探すために使うことができる文字列です。 +どんな文字列も`.r`メソッドを使うことで、正規表現に変換できます。 + +```tut +import scala.util.matching.Regex + +val numberPattern: Regex = "[0-9]".r + +numberPattern.findFirstMatchIn("awesomepassword") match { + case Some(_) => println("Password OK") + case None => println("Password must contain a number") +} +``` +上記の例では、`numberPattern`は`Regex`(正規表現)型で、パスワードに数字が含まれていることを確認するのに使います。 + +括弧を使うことで、正規表現のグループを探すこともできます。 + +```tut +import scala.util.matching.Regex + +val keyValPattern: Regex = "([0-9a-zA-Z-#() ]+): ([0-9a-zA-Z-#() ]+)".r + +val input: String = + """background-color: #A03300; + |background-image: url(img/header100.png); + |background-position: top center; + |background-repeat: repeat-x; + |background-size: 2160px 108px; + |margin: 0; + |height: 108px; + |width: 100%;""".stripMargin + +for (patternMatch <- keyValPattern.findAllMatchIn(input)) + println(s"key: ${patternMatch.group(1)} value: ${patternMatch.group(2)}") +``` +ここでは、文字列のキーと値を解析しています。 +それぞれのマッチはサブマッチのグループを持ちます。こちらが出力結果です。 +``` +key: background-color value: #A03300 +key: background-image value: url(img/header100.png) +key: background-position value: top center +key: background-repeat value: repeat-x +key: background-size value: 2160px 108px +key: margin value: 0 +key: height value: 108px +key: width value: 100 +``` diff --git a/_ja/tour/self-types.md b/_ja/tour/self-types.md new file mode 100644 index 0000000000..836e4459ec --- /dev/null +++ b/_ja/tour/self-types.md @@ -0,0 +1,42 @@ +--- +layout: tour +title: 自分型 +language: ja + +discourse: true + +partof: scala-tour + +num: 25 +next-page: implicit-parameters +previous-page: compound-types +topics: self-types +prerequisite-knowledge: nested-classes, mixin-class-composition + +redirect_from: "/tutorials/tour/self-types.html" +--- +自分型は、直接継承していなくてもトレイトが他のトレイトにミックスインされていることを宣言する方法です。 +これにより依存先のメンバーをimportなしで利用できます。 + +自分型は`this`、または`this`の別名となる他の識別子の型を絞り込む方法です。 +その構文は普通の関数構文のように見えますが、全く異なる意味があります。 + +トレイトで自分型を使うには、識別子、ミックスインする他のトレイトの型、`=>`を書きます(例えば `someIdentifier: SomeOtherTrait =>`)。 +```tut +trait User { + def username: String +} + +trait Tweeter { + this: User => // thisが再割り当てされます + def tweet(tweetText: String) = println(s"$username: $tweetText") +} + +class VerifiedTweeter(val username_ : String) extends Tweeter with User { // TweeterがUserを必要とするためミックスインします。 + def username = s"real $username_" +} + +val realBeyoncé = new VerifiedTweeter("Beyoncé") +realBeyoncé.tweet("Just spilled my glass of lemonade") // "real Beyoncé: Just spilled my glass of lemonade"と出力します。 +``` +`trait Tweeter`の中で`this: User =>`と記述したので、今は変数`username`は`tweet`メソッドのスコープ内にあります。これはさらに、`VerifiedTweeter`が`Tweeter`を継承する際、(`with User`を使って)`User`もミックスインしなければならいことを意味します。 diff --git a/_ja/tour/singleton-objects.md b/_ja/tour/singleton-objects.md new file mode 100644 index 0000000000..e920e884c9 --- /dev/null +++ b/_ja/tour/singleton-objects.md @@ -0,0 +1,122 @@ +--- +layout: tour +title: シングルトンオブジェクト +language: ja + +discourse: true + +partof: scala-tour + +num: 13 + +next-page: regular-expression-patterns +previous-page: pattern-matching +redirect_from: "/tutorials/tour/singleton-objects.html" +prerequisite-knowledge: classes, methods, private-methods, packages, option +--- +オブジェクトは丁度1つのインスタンスを持つクラスです。 +それはlazy valのように参照された際に遅れて作られます。 + +トップレベルにあるオブジェクトは、シングルトンです。 +クラスのメンバーやローカル変数としてのオブジェクトは、lazy valと全く同じように振る舞います。 + +# シングルトンオブジェクトの定義 +オブジェクトは値です。オブジェクトの定義はクラスのように見えますが、キーワード`object`を使います。 +```tut +object Box +``` +これはメソッドを持つオブジェクトの例です。 +``` +package logging + +object Logger { + def info(message: String): Unit = println(s"INFO: $message") +} +``` +`info`メソッドはプログラム上のどこからでもimportすることができます。 +このように便利なメソッドを作ることはシングルトンオブジェクトのユースケースと同じです。 + +他のパッケージで`info`がどのように使われるか見てみましょう。 + +``` +import logging.Logger.info + +class Project(name: String, daysToComplete: Int) + +class Test { + val project1 = new Project("TPS Reports", 1) + val project2 = new Project("Website redesign", 5) + info("Created projects") // Prints "INFO: Created projects" +} +``` + +import文`import logging.Logger.info`により、`info`メソッドが見えるようになります。 + +import文には取り込むシンボルへの"変動しないパス"が必要であり、オブジェクトは変動しないパスとなります。 + +注意:`object`がトップレベルではなく他のクラスやオブジェクトにネストされている時、そのオブジェクトは他のメンバーのように"経路依存性"があります。 +これは2種類の飲み物`class 牛乳`と`class オレンジジュース`が与えられた場合、クラスメンバーの`object 栄養素`はそれが属するインスタンス、すなわち牛乳またはオレンジジュースのいずれかに依存することを意味します。 +`milk.NutritionInfo`は`oj.NutritionInfo`とは全く異なります。 + +## コンパニオンオブジェクト + +クラスと同じ名前のオブジェクトは*コンパニオンオブジェクト*と呼ばれます。 +逆にそのクラスはオブジェクトのコンパニオンクラスと呼ばれます。 +コンパニオンクラスやコンパニオンオブジェクトは自身のコンパニオンのプライベートメンバーにアクセスできます。 +コンパニオンクラスのインスタンスに特定されないメソッドや値にはコンパニオンオブジェクトを使います。 + +``` +import scala.math._ + +case class Circle(radius: Double) { + import Circle._ + def area: Double = calculateArea(radius) +} + +object Circle { + private def calculateArea(radius: Double): Double = Pi * pow(radius, 2.0) +} + +val circle1 = new Circle(5.0) + +circle1.area +``` + +`class Circle`は各インスタンスの固有のメンバー`area`を持ち、シングルトンオブジェクト`object Circle`は全てのインスタンスで利用できる`calculateArea`メソッドを持ちます。 + +コンパニオンオブジェクトはファクトリーメソッドを含むことができます。 +```tut +class Email(val username: String, val domainName: String) + +object Email { + def fromString(emailString: String): Option[Email] = { + emailString.split('@') match { + case Array(a, b) => Some(new Email(a, b)) + case _ => None + } + } +} + +val scalaCenterEmail = Email.fromString("scala.center@epfl.ch") +scalaCenterEmail match { + case Some(email) => println( + s"""Registered an email + |Username: ${email.username} + |Domain name: ${email.domainName} + """) + case None => println("Error: could not parse email") +} +``` +`object Email`はファクトリー`fromString`を持ち、Stringから`Email`インスタンスを作ります。 +パースエラーの場合も考えて、返り値の型を`Option[Email]`とします。 + +注意:クラスまたはオブジェクトがコンパニオンを持つ場合、クラス、オブジェクトの両方は同じファイルの中に定義されていなければなりません。 +REPL内でコンパニオンを定義する場合は、それらを同じ行で定義するか、`:paste`モードに入ります。 + +## Javaプログラマのための注意事項 ## + +Javaにおける`static`メンバーはScalaではコンパニオンオブジェクトの一般メンバーとして作られています。 + +Javaのコードからコンパニオンオブジェクトを使う場合、メンバーはコンパニオンクラス内で`static`識別子を用いて定義されます。 +これは*static forwarding*と呼ばれます。 +これはコンパニオンクラスを自分で定義していなかったとしても起きます。 diff --git a/_ja/tour/tour-of-scala.md b/_ja/tour/tour-of-scala.md new file mode 100644 index 0000000000..775c66557f --- /dev/null +++ b/_ja/tour/tour-of-scala.md @@ -0,0 +1,86 @@ +--- +layout: tour +title: 前書き +language: ja + +discourse: true + +partof: scala-tour + +num: 1 + +next-page: basics + +redirect_from: "/tutorials/tour/tour-of-scala.html" +--- + +## ようこそツアーへ +このツアーはScalaで最もよく使う機能を一口サイズで紹介をしています。 +これらはScala初心者を対象としています。 + +これはほんの短いツアーで、完全な言語のチュートリアルではありません。 +もしそれを望むなら、[こちらの本](/books.html) を手に入れるか、 +[その他の解決手段](/learn.html) での相談を検討してください。 + +## Scalaとは? +Scalaは一般的なプログラミング方法を簡潔かつエレガントかつ型安全な方法で表現するために設計されたモダンなマルチパラダイム言語です。 +それはオブジェクト指向言語と関数型言語の機能をスムーズに統合しています。 + +## Scalaはオブジェクト指向 ## +Scalaは[全ての値がオブジェクトである](unified-types.html) という意味では純粋オブジェクト指向言語です。 +型とオブジェクトの振る舞いは[クラス](classes.html) と[トレイト](traits.html) によって記述されます。 +クラスはサブクラス化と、多重継承を巧みに置き換える柔軟な[ミックスインを基にした合成](mixin-class-composition.html) 機構により拡張されます。 + +## Scalaは関数型 ## +Scalaは[すべての関数が値である](unified-types.html) という意味で関数型言語でもあります。 +Scalaは無名関数を定義するために[軽量な構文](basics.html#関数)を提供し、 +[高階関数](higher-order-functions.html) をサポートし、関数は[ネスト](nested-functions.html)しても良く、[カリー化](multiple-parameter-lists.html) をサポートします。 +Scalaの[ケースクラス](case-classes.html)には[パターンマッチング](pattern-matching.html)が組み込まれていることにより、多くの関数型プログラミング言語で使われる代数型を作ることができます。 +[シングルトンオブジェクト](singleton-objects.html) はクラスのメンバーではない関数をグループ化する便利な方法を提供します。 + +さらに、Scalaのパターンマッチングの概念は、[抽出子オブジェクト](extractor-objects.html) による一般的な拡張として、[右無視シーケンスパターン](regular-expression-patterns.html)の働きにより、自然に[XMLデータの処理](https://github.com/scala/scala-xml/wiki/XML-Processing) にまで拡張されています。 +(訳者註:現在のバージョンでは右無視シーケンスパターンの説明は正規表現のページから除かれています。[→古いバージョン](https://www.scala-lang.org/old/node/122)) +この文脈では、For内包表記はクエリの設計に役立ちます。 +これらの機能により、ScalaはWebサービスのようなアプリケーション開発に理想的なものとなっています。 + +## Scalaは静的型付け ## +Scalaは抽象化が安全で首尾一貫した方法で使われることをコンパイル時に強制する、表現力豊かな型システムを備えています。 +特にその型システムは以下をサポートします: + +* [ジェネリッククラス](generic-classes.html) +* [変位指定アノテーション](variances.html) +* [上限](upper-type-bounds.html) と [下限](lower-type-bounds.html) 型境界 +* [内部クラス](inner-classes.html) とオブジェクトメンバーとしての[抽象型メンバー](abstract-type-members.html) +* [複合型](compound-types.html) +* [明示的に型指定された自己参照](self-types.html) +* [暗黙パラメーター](implicit-parameters.html) と [暗黙の変換](implicit-conversions.html) +* [ポリモーフィックメソッド](polymorphic-methods.html) + +[型推論](type-inference.html) は、ユーザーがコードに冗長な型情報の注釈をつける必要はないことを意味します。 +これらの機能を組み合わせることにより、プログラミングの抽象化を安全に再利用でき、ソフトウェアを型安全に拡張できる強力な基盤となります。 + +## Scalaは拡張可能 ## + +実際問題として、ドメイン固有のアプリケーションの開発ではよくドメイン固有の言語拡張が必要となります。 +Scalaは言語メカニズムのユニークな組み合わせを提供します。それにより、新しい言語構成要素をライブラリという形で円滑に追加することを簡単にします。 + +多くのケースで、これはマクロのようなメタプログラミングの機能を使わずに実現できます。例えば、 + +* [暗黙のクラス](http://docs.scala-lang.org/overviews/core/implicit-classes.html) で既存の型に拡張メソッドを追加できます。 + +* [文字列補間](/ja/overviews/core/string-interpolation.html) はカスタム補間を使ってユーザー拡張可能です。 + +## Scalaの相互運用 + +Scalaは一般的なJava実行環境 (JRE) と相互運用するように設計されています。 +特に、主流であるオブジェクト指向のJavaプログラミング言語とのやり取りはできるだけスムーズになっています。 +ScalaではSAMs、[ラムダ](higher-order-functions.html) 、[アノテーション](annotations.html) 、[ジェネリクス](generic-classes.html) のようなJavaの新しい機能には直接の類似物があります。 + +[デフォルト引数](default-parameter-values.html) 、[名前付きパラメータ](named-arguments.html) +といった、Javaに類似物がないScalaの機能はできるだけ適切でJavaに近い形にコンパイルされます。 +ScalaはJavaのような同じコンパイルモデル(分割コンパイル、動的クラス読み込み) を持っており、数千の既存の高品質なライブラリにアクセスができます。 + +## ツアーを楽しんで! + +もっと読むには、目次メニューの[次のページ](basics.html) に進んでください。 + diff --git a/_ja/tour/traits.md b/_ja/tour/traits.md new file mode 100644 index 0000000000..1ea0b11809 --- /dev/null +++ b/_ja/tour/traits.md @@ -0,0 +1,89 @@ +--- +layout: tour +title: トレイト +language: ja + +discourse: true + +partof: scala-tour + +num: 5 +next-page: tuples +previous-page: classes +topics: traits +prerequisite-knowledge: expressions, classes, generics, objects, companion-objects + +redirect_from: "/tutorials/tour/traits.html" +--- + +トレイトはクラス間でインターフェースとフィールドを共有するために使います。それらはJava 8のインターフェースと似ています。 +クラスとオブジェクトはトレイトを継承することができますが、トレイトはインスタンス化ができません、したがってパラメータを持ちません。 + +## トレイトを定義する +最小のトレイトはキーワード `trait` と識別子だけというものです。 + +```tut +trait HairColor +``` + +トレイトはジェネリック型として、抽象メソッドとあわせて使うと特に便利です。 +```tut +trait Iterator[A] { + def hasNext: Boolean + def next(): A +} +``` + +`trait Iterator[A]` を継承することは `A` 型と、`hasNext` と `next` メソッドの実装を必要とします。 + +## トレイトの使い方 +トレイトを継承するには `extends` キーワードを使います。その際に、 `override` キーワードを利用しすべての抽象メンバーを実装します。 +```tut +trait Iterator[A] { + def hasNext: Boolean + def next(): A +} + +class IntIterator(to: Int) extends Iterator[Int] { + private var current = 0 + override def hasNext: Boolean = current < to + override def next(): Int = { + if (hasNext) { + val t = current + current += 1 + t + } else 0 + } +} + + +val iterator = new IntIterator(10) +iterator.next() // returns 0 +iterator.next() // returns 1 +``` +ここでの `IntIterator` クラスは上限として引数 `to` を取ります。 +`extends Iterator[Int]` は `next` メソッドは Int を返さなければならないことを意味します。 + +## サブタイピング +あるトレイトが必要とされている場所に、代りにそのトレイトのサブタイプを使うことができます。 + +```tut +import scala.collection.mutable.ArrayBuffer + +trait Pet { + val name: String +} + +class Cat(val name: String) extends Pet +class Dog(val name: String) extends Pet + +val dog = new Dog("Harry") +val cat = new Cat("Sally") + +val animals = ArrayBuffer.empty[Pet] +animals.append(dog) +animals.append(cat) +animals.foreach(pet => println(pet.name)) // Prints Harry Sally +``` +`trait Pet` が持つ抽象フィールド `name`は、Cat と Dog のコンストラクタで実装されました。 +最終行では、`Pet` トレイトの全てのサブタイプの中で実装される必要がある `pet.name` を呼んでいます。 diff --git a/_ja/tour/tuples.md b/_ja/tour/tuples.md new file mode 100644 index 0000000000..0d67f6c5c1 --- /dev/null +++ b/_ja/tour/tuples.md @@ -0,0 +1,79 @@ +--- +layout: tour +title: タプル +language: ja + +discourse: true + +partof: scala-tour + +num: 6 +next-page: mixin-class-composition +previous-page: traits +topics: tuples + +redirect_from: "/tutorials/tour/tuples.html" +--- + +Scalaではタプルは決まった数の要素を含む値であり、各要素はそれぞれの型を持ちます。 +タプルは不変です。 + +タプルはメソッドから複数の値を返す際に特に役立ちます。 + +2つの要素を持つタプルは以下のように作ることができます。 + +```tut +val ingredient = ("Sugar" , 25) +``` +ここでは`String`要素を1つと`Int`要素を1つ含むタプルを作っています。 + +推論される`ingredient`の型は`(String, Int)`であり、これは`Tuple2[String, Int]`の簡単な表記法です。 + +タプルを表すために、Scalaは`Tuple2`, `Tuple3` … `Tuple22`までのクラス群を使います。 +それぞれのクラスは要素の数と同じ数の型パラメータを持ちます。 + +## 要素へのアクセス + +タプルの要素へのアクセス方法の1つとして、位置があります。 +個々の要素は`_1`、`_2`などと名付けられます。 + +```tut +println(ingredient._1) // Sugar +println(ingredient._2) // 25 +``` +## タプルでのパターンマッチング +タプルはパターンマッチングを使って分解することもできます。 + +```tut +val (name, quantity) = ingredient +println(name) // Sugar +println(quantity) // 25 +``` + +ここでは`name`に推論される型は`String`で、`quantity`に推論される型は`Int`です。 + +こちらはタプルのパターンマッチングの他の例です。 + +```tut +val planets = + List(("Mercury", 57.9), ("Venus", 108.2), ("Earth", 149.6), + ("Mars", 227.9), ("Jupiter", 778.3)) +planets.foreach{ + case ("Earth", distance) => + println(s"Our planet is $distance million kilometers from the sun") + case _ => +} +``` + +また、`for`内包表記では以下のようになります。 + +```tut +val numPairs = List((2, 5), (3, -7), (20, 56)) +for ((a, b) <- numPairs) { + println(a * b) +} +``` + +## タプルとケースクラス +ユーザーは時々、タプルとケースクラスの選択を難しいと思うかもしれません。ケースクラスには名前付き要素があります。それらの名前によってコードの可読性を改善できる場合があります。 +上記の惑星の例ではタプルを使うより、`case class Planet(name: String, distance: Double)`を定義したほうがいいかもしれません。 diff --git a/_ja/tour/type-inference.md b/_ja/tour/type-inference.md new file mode 100644 index 0000000000..5a0dc8c4a7 --- /dev/null +++ b/_ja/tour/type-inference.md @@ -0,0 +1,74 @@ +--- +layout: tour +title: 型推論 +language: ja + +discourse: true + +partof: scala-tour + +num: 29 +next-page: operators +previous-page: polymorphic-methods +--- + +Scalaコンパイラが式の型を推論できることが多いので、明示的に型を宣言する必要はありません。 + +## 型の省略 + +```tut +val businessName = "Montreux Jazz Café" +``` +コンパイラは`businessName`がStringだと検知できます。これはメソッドでも同様に動きます。 + +```tut +def squareOf(x: Int) = x * x +``` +コンパイラは戻り値の型が`Int`だと推論できるので、明示的な戻り値の型は必要ありません。 + +再帰的メソッドでは、コンパイラは結果の型を推論できません。こちらはこの理由でコンパイラが失敗するプログラムです。 + +```tut:fail +def fac(n: Int) = if (n == 0) 1 else n * fac(n - 1) +``` + +[ポリモーフフィックメソッド](polymorphic-methods.html)が呼ばれる時や[ジェネリッククラス](generic-classes.html) がインスタンス化される場合も型パラメータの指定は強制ではありません。Scalaコンパイラは文脈あるいはメソッドやコンストラクタの実際の引数から、指定されていない型パラメータを推論します。 + +こちらは2つの例です。 + +```tut +case class MyPair[A, B](x: A, y: B); +val p = MyPair(1, "scala") // 型: MyPair[Int, String] + +def id[T](x: T) = x +val q = id(1) // 型: Int +``` +コンパイラは型`A`と`B`が何であるかを見つけ出すために`MyPair`の引数の型を使用します。`x`の型も同様です。 + +## パラメータ + +コンパイラはメソッドのパラメータ型を決して推論しません。しかし、関数が引数として渡されている場合は、無名関数のパラメータ型を推論できます。 + +```tut +Seq(1, 3, 4).map(x => x * 2) // List(2, 6, 8) +``` + +mapのパラメータは`f: A => B`です。`Seq`の中に整数が入っているので、コンパイラは`A`が`Int`だと知っています(つまり、この`x`は整数です)。したがってコンパイラは`x * 2`から`B`が型`Int`であると推論できます。 + +## 型推論に頼ら*ない*時 + +一般的には、パブリックなAPIで公開されているメンバーの型を宣言したほうが読みやすいと考えられています。そのため、ユーザーに公開するAPIではあなたのコードの型を明示することをお勧めします。 + +また、型推論は特定の型を推論することがあります。次のように書いたとします。 + +```tut +var obj = null +``` + +これ以上進められず、再割り当てができません。 + +```tut:fail +obj = new AnyRef +``` + +こちらはコンパイルできません。`obj`に推論された型は`Null`だからです。その型の唯一の値が`null`なので、他の値を代入できれません。 diff --git a/_ja/tour/unified-types.md b/_ja/tour/unified-types.md new file mode 100644 index 0000000000..98482b1c95 --- /dev/null +++ b/_ja/tour/unified-types.md @@ -0,0 +1,97 @@ +--- +layout: tour +title: 統合された型 +language: ja + +discourse: true + +partof: scala-tour + +num: 3 +next-page: classes +previous-page: basics +prerequisite-knowledge: classes, basics + +redirect_from: "/tutorials/tour/unified-types.html" +--- +Scalaでは数値や関数を含め、全ての値は型を持ちます。 +以下の図は型階層の一部を説明しています。 + +Scala Type Hierarchy + +## Scalaの型階層 ## + +[`Any`](http://www.scala-lang.org/api/2.12.1/scala/Any.html) は全ての型のスーパータイプであり、トップ型とも呼ばれます。 +Anyは `equals`、` hashCode`、そして `toString`のようないくつかの普遍的なメソッドを定義しています。 +そして`AnyVal`と`AnyRef` という2つの直系のサブクラスを持ちます。 + +`AnyVal` は値型に相当します。 +事前に定義された9つの値型が存在し、それら`Double`, `Float`, `Long`, `Int`, `Short`, `Byte`, `Char`, `Unit`,`Boolean`は +null非許容です。 +`Unit`は意味のある情報をもたない値型です。`Unit`型のインスタンスはただ1つだけあり、`()`というリテラルで宣言することができます。 +全ての関数は必ず何かを返さなければなりません。そのため`Unit`は戻り値の型として時々役立ちます。 + +`AnyRef` は参照型を意味します。全ての値型でない型は参照型として定義されます。Scalaでは全てのユーザー定義型は`AnyRef`のサブタイプになります。 +もしScalaがJava実行環境上で利用されるなら、`AnyRef` は `java.lang.Object` に相当します。 + +以下にstring、integer、character、boolean、関数が他のオブジェクトと同様に全てオブジェクトであるという例を示します。 + +```tut +val list: List[Any] = List( + "a string", + 732, // integer + 'c', // character + true, // boolean value + () => "文字列を返す無名関数" +) + +list.foreach(element => println(element)) +``` + +これは`List[Any]`型の`list`という値を定義します。 +このlistは様々な型の要素で初期化されています。しかしそれぞれの要素は `scala.Any` のインスタンスなのでlistに追加することができています。 + +こちらは先程のプログラムの出力です。 + +``` +a string +732 +c +true + +``` + +## 型キャスト +値型は以下の順序でキャストできます。 + +Scalaの型階層 + +例えば、 + +```tut +val x: Long = 987654321 +val y: Float = x // 9.8765434E8 (この場合精度が落ちることに注意してください) + +val face: Char = '☺' +val number: Int = face // 9786 +``` + +型変換は一方向です。これはコンパイルができないでしょう。 + +``` +val x: Long = 987654321 +val y: Float = x // 9.8765434E8 +val z: Long = y // 一致しない +``` + +参照型をサブタイプにキャストすることもできます。こちらはツアーの中で後ほど紹介します。 + +## Nothing と Null +`Nothing`は全ての型のサブタイプであり、ボトム型とも呼ばれます。`Nothing`型を持つ値は存在しません。 +一般的に例外のスロー、プログラム終了、無限ループなど終了していないことを示すのに使われます。 +(すなわち、値として評価されない式や正常に返らないメソッドなどです。) + + +`Null` は全ての参照型のサブタイプ(すなわち、全てのAnyRefのサブタイプ)です。`null`というキーワードリテラルが指す値を1つだけもちます。 +`Null` は、ほぼ他のJVM言語との相互運用性のためだけに提供されているので、Scalaのコード内ではほとんどの場合、使われるべきではありません。 +`null`の代替手段については、後のツアーで説明します。 diff --git a/_ja/tour/upper-type-bounds.md b/_ja/tour/upper-type-bounds.md new file mode 100644 index 0000000000..427dbe429f --- /dev/null +++ b/_ja/tour/upper-type-bounds.md @@ -0,0 +1,60 @@ +--- +layout: tour +title: 上限型境界 +language: ja + +discourse: true + +partof: scala-tour +categories: tour +num: 20 +next-page: lower-type-bounds +previous-page: variances + +redirect_from: "/tutorials/tour/upper-type-bounds.html" +--- + +Scalaでは [型パラメータ](generic-classes.html)と[抽象型メンバー](abstract-type-members.html) は型境界による制約をかけることができます。 +型境界は型変数に入れられる具象型を制限して、時にはそれらの型のメンバーについてより多くの情報を与えます。 +_上限型境界_ `T <: A` は型変数`T`が型`A`のサブタイプであるという宣言です。 + +こちらはクラス`PetContainer`の型パラメータの上限型境界を実演する例です。 + +```tut +abstract class Animal { + def name: String +} + +abstract class Pet extends Animal {} + +class Cat extends Pet { + override def name: String = "Cat" +} + +class Dog extends Pet { + override def name: String = "Dog" +} + +class Lion extends Animal { + override def name: String = "Lion" +} + +class PetContainer[P <: Pet](p: P) { + def pet: P = p +} + +val dogContainer = new PetContainer[Dog](new Dog) +val catContainer = new PetContainer[Cat](new Cat) +``` + +```tut:fail +// これはコンパイルされません +val lionContainer = new PetContainer[Lion](new Lion) +``` +`class PetContainer`は型パラメータ`P`を受け取ります。それは`Pet`のサブタイプである必要があります。 + `Dog`と`Cat`は`Pet`のサブタイプなので、新たな`PetContainer[Dog]`と`PetContainer[Cat]`を作ることができます。 + しかしながら、もし`PetContainer[Lion]`を作ろうとすると、以下のエラーが返ってきます。 + +`type arguments [Lion] do not conform to class PetContainer's type parameter bounds [P <: Pet]` + +これは`Lion`は`Pet`のサブタイプではないからです。 diff --git a/_ja/tour/variances.md b/_ja/tour/variances.md new file mode 100644 index 0000000000..35f0d01de8 --- /dev/null +++ b/_ja/tour/variances.md @@ -0,0 +1,184 @@ +--- +layout: tour +title: 変位指定 +language: ja + +discourse: true + +partof: scala-tour + +num: 19 +next-page: upper-type-bounds +previous-page: generic-classes + +redirect_from: "/tutorials/tour/variances.html" +--- + +変位指定は複合型の間の継承関係とそれらの型パラメータ間の継承関係の相関です。 +Scalaは[ジェネリッククラス](generic-classes.html)の型パラメータの変位指定アノテーションをサポートしています。 +変位指定アノテーションにより共変、反変にでき、アノテーション無しなら非変になります。 +型システム上で変位指定を利用すると複合型間の直感的な繋がりを作ることができます。 +もし変位指定が無ければ、クラスを抽象化して再利用しにくくなるでしょう。 + + +```tut +class Foo[+A] // 共変クラス +class Bar[-A] // 反変クラス +class Baz[A] // 非変クラス +``` + +### 共変 + +ジェネリッククラスの型パラメータ`A`はアノテーション`+A`を使うと共変になります。 +`class List[+A]`では、`A`が共変になっているので、`A`が`B`のサブタイプであるような`A`と`B`に対して`List[A]`が`List[B]`のサブタイプであることを示します。 +これによりジェネリックを利用したとても便利で直感的なサブタイプの関係を作ることができます。 + +このシンプルなクラス構成を考えてみましょう。 + +```tut +abstract class Animal { + def name: String +} +case class Cat(name: String) extends Animal +case class Dog(name: String) extends Animal +``` +`Cat`と`Dog`は`Animal`のサブタイプです。 +Scala標準ライブラリにはイミュータブルなジェネリッククラス`sealed abstract class List[+A]`があり、型パラメータ`A`が共変です。 +これは`List[Cat]`は`List[Animal]`であり、`List[Dog]`も`List[Animal]`であることを意味します。 +猫のリストも犬のリストも動物のリストであり、どちらも`List[Animal]`の代わりにできる、というのは直感的に理解できます。 + +以下の例では、メソッド`printAnimalNames`は引数に動物のリストを受け取り、新しい行にそれらの名前をプリントします。 +もし`List[A]`が共変でなければ、最後の2つのメソッド呼び出しはコンパイルされず、`printAnimalNames`メソッドの使い勝手はひどく制限されます。 + +```tut +object CovarianceTest extends App { + def printAnimalNames(animals: List[Animal]): Unit = { + animals.foreach { animal => + println(animal.name) + } + } + + val cats: List[Cat] = List(Cat("Whiskers"), Cat("Tom")) + val dogs: List[Dog] = List(Dog("Fido"), Dog("Rex")) + + printAnimalNames(cats) + // Whiskers + // Tom + + printAnimalNames(dogs) + // Fido + // Rex +} +``` + +### 反変 + +ジェネリッククラスの型パラメータ`A`はアノテーション`-A`を利用して反変にできます。 +これはクラスとその型パラメータの間で、共変と似ていますが反対の意味のサブタイプ関係を作ります。 + +`class Writer[-A]`では`A`が反変になっているので、`A`が`B`のサブタイプであるような`A`と`B`に対し、`Writer[B]`が`Writer[A]`のサブタイプであることを示します。 + +先に定義された`Cat`、`Dog`、`Animal`クラスを以下の例で検討してみます。 + +```tut +abstract class Printer[-A] { + def print(value: A): Unit +} +``` +`Printer[A]`はある型`A`をどのようにプリントするかを知っている簡単なクラスです。 +特定の型でいくつかのサブクラスを定義してみましょう。 + +```tut +class AnimalPrinter extends Printer[Animal] { + def print(animal: Animal): Unit = + println("The animal's name is: " + animal.name) +} + +class CatPrinter extends Printer[Cat] { + def print(cat: Cat): Unit = + println("The cat's name is: " + cat.name) +} +``` +`Printer[Cat]`はコンソールに任意の`Cat`をプリントする方法を知っています。 +そして`Printer[Animal]`はコンソールに任意の`Animal`をプリントする方法を知っています。 +それは`Printer[Animal]`も任意の`Cat`をプリントする方法を知っていることを意味します。 +逆の関係性は適用されません、それは`Printer[Cat]`がコンソールに任意の`Animal`をプリントする方法を知らないからです。 +したがって、私達は必要であれば`Printer[Animal]`を`Printer[Cat]`代わりに使うことができます。これは`Printer[A]`が反変であるからこそ可能なのです。 + +```tut +object ContravarianceTest extends App { + val myCat: Cat = Cat("Boots") + + def printMyCat(printer: Printer[Cat]): Unit = { + printer.print(myCat) + } + + val catPrinter: Printer[Cat] = new CatPrinter + val animalPrinter: Printer[Animal] = new AnimalPrinter + + printMyCat(catPrinter) + printMyCat(animalPrinter) +} +``` + +この出力結果は以下のようになります。 + +``` +The cat's name is: Boots +The animal's name is: Boots +``` + +### 非変 + +Scalaのジェネリッククラスは標準では非変です。 +これは共変でも反変でもないことを意味します。 +以下の例の状況では、`Container`クラスは非変です。`Container[Cat]`は`Container[Animal]`_ではなく_、逆もまた同様です。 + +```tut +class Container[A](value: A) { + private var _value: A = value + def getValue: A = _value + def setValue(value: A): Unit = { + _value = value + } +} +``` +`Container[Cat]`が `Container[Animal]`でもあることは自然なように思えるかもしれませんが、ミュータブルジェネリッククラスを共変にするのは安全ではありません。 +この例では、`Container`が非変であることは非常に重要です。`Container`が仮に共変だったとするとこのようなことが起こり得ます。 + +``` +val catContainer: Container[Cat] = new Container(Cat("Felix")) +val animalContainer: Container[Animal] = catContainer +animalContainer.setValue(Dog("Spot")) +val cat: Cat = catContainer.getValue // おっと、犬に猫に割り当ててしまった。 +``` + +幸いにも、実行する前にコンパイラが止めてくれます。 + +### 他の例 + +変位指定の理解を助けるもう一つの例はScala標準ライブラリの`trait Function1[-T, +R]`です。 +`Function1`は1つのパラメータを持つ関数を表します。1つ目の型パラメータ`T`はパラメータの型を表します。 +そして2つ目の型パラメータ`R`は戻り値の型を表します。 +`Function1`はその引数の型に対して反変であり、戻り値の型に対して共変です。 +この例では`Function1[A, B]`を表現するために`A => B`という文字での表記をします。 + +先ほど利用された`Cat`, `Dog`, `Animal`の継承ツリーに、以下のものを加えましょう: + +```tut +abstract class SmallAnimal extends Animal +case class Mouse(name: String) extends SmallAnimal +``` + +動物の種類を受け取り、それらが食べる食料の種類を返す関数がいくつかあるとしましょう。 +もし(猫は小動物を食べるので)`Cat => SmallAnimal`が欲しい場合に代わりに`Animal => Mouse`を与えられたとしても、私たちのプログラムはまだ動きます。 +直感的に、`Cat`は`Animal`なので、`Animal => Mouse` は`Cat`を引数として受け取ります。 +そして`SmallAnimal`である`Mouse`を返します。 + +安全に、そのままで前者に代えて後者を用いることができるため、`Animal => Mouse`は`Cat => SmallAnimal`のサブタイプと言うことができます。 + +### 他の言語との比較 + +Scalaに似たいくつかの言語で、変位指定はいろんな方法でサポートされています。 +例えば、Scalaの変位指定アノテーションはC#のそれと非常に似ています。C#ではクラスの抽象性を定義する時にアノテーションが追加されます(宣言時の変位指定)。 +しかしながら、Javaでは、クラスの抽象性を使う時に変位指定アノテーションが利用側のコードから与えられます(使用時の変位指定)。 From 3308d9fae3cdf58ea122d7de98bd2002c3b870c7 Mon Sep 17 00:00:00 2001 From: Eugene Kim Date: Thu, 27 Jun 2019 00:45:44 +0900 Subject: [PATCH 0542/3075] Fix deprecated method definition change a part of the source "def move(dx: Int, dy: Int) {" instead of "def move(dx: Int, dy: Int): Unit = {" "def main(args: Array[String]) {" ---> "def main(args: Array[String]): Unit = {" --- _ko/tour/classes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_ko/tour/classes.md b/_ko/tour/classes.md index 0e3a54f558..e2aebe798b 100644 --- a/_ko/tour/classes.md +++ b/_ko/tour/classes.md @@ -19,7 +19,7 @@ previous-page: unified-types class Point(xc: Int, yc: Int) { var x: Int = xc var y: Int = yc - def move(dx: Int, dy: Int) { + def move(dx: Int, dy: Int): Unit = { x = x + dx y = y + dy } @@ -33,7 +33,7 @@ previous-page: unified-types 클래스들은 아래의 예제가 보여주는 것처럼 새로운 기본형으로 초기화된다. object Classes { - def main(args: Array[String]) { + def main(args: Array[String]): Unit = { val pt = new Point(1, 2) println(pt) pt.move(10, 10) From 9b14836791fe9b15ff161b496491762aebe1cdee Mon Sep 17 00:00:00 2001 From: Patrick Moore Date: Wed, 26 Jun 2019 10:28:32 -0700 Subject: [PATCH 0543/3075] Update scala-for-java-programmers.md Java 8 has java.util.function package. Java 8 was released in 2014 (5 years ago). At this point in time, Java developers are *not* surprised about being able to manipulate functions as values and pass them as arguments. --- _overviews/tutorials/scala-for-java-programmers.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_overviews/tutorials/scala-for-java-programmers.md b/_overviews/tutorials/scala-for-java-programmers.md index 3ed8305c2a..9daab8070e 100644 --- a/_overviews/tutorials/scala-for-java-programmers.md +++ b/_overviews/tutorials/scala-for-java-programmers.md @@ -155,7 +155,7 @@ Scala is a pure object-oriented language in the sense that *everything* is an object, including numbers or functions. It differs from Java in that respect, since Java distinguishes primitive types (such as `boolean` and `int`) from reference -types, and does not enable one to manipulate functions as values. +types. ### Numbers are objects @@ -190,7 +190,7 @@ prevents `1` from being interpreted as a `Double`. ### Functions are objects -Perhaps more surprising for the Java programmer, functions are also +Functions are also objects in Scala. It is therefore possible to pass functions as arguments, to store them in variables, and to return them from other functions. This ability to manipulate functions as values is one of From 0caa894bfe10fb4f50d5b0b9846f62781de90fd4 Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Fri, 28 Jun 2019 14:04:08 +0800 Subject: [PATCH 0544/3075] (tutorials) Fix pr#1405 for zh-cn. --- _zh-cn/tutorials/scala-for-java-programmers.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_zh-cn/tutorials/scala-for-java-programmers.md b/_zh-cn/tutorials/scala-for-java-programmers.md index f25a39db69..b5fcb5770e 100644 --- a/_zh-cn/tutorials/scala-for-java-programmers.md +++ b/_zh-cn/tutorials/scala-for-java-programmers.md @@ -87,7 +87,7 @@ Scala 的导入表达式跟 Java 非常像,但更为强大。如第一行, ## 一切都是对象 -Scala 是一个纯粹的面向对象语言,这句话的意思是说,*所有东西*都是对象,包括数字、函数。因为 Java 将基本类型 (如 `boolean` 与 `int` ) 跟参照类型分开,而且没有办法像操作变量一样操作函数,从这角度来看 Scala 跟 Java 是不同的。 +Scala 是一个纯粹的面向对象语言,意即包括数字、函数在内的*所有东西*都是对象。这跟 Java 不同,因为 Java 的基本类型 (如 `boolean` 与 `int` ) 和引用类型是有区别的。 ### 数字是对象 @@ -113,7 +113,7 @@ Scala 是一个纯粹的面向对象语言,这句话的意思是说,*所有 ### 函数是对象 -可能令 Java 程序员更为惊讶的会是,Scala 中函数也是对象。因此,将函数当做对象传递、把它们存入变量、从其他函数返回函数都是可能的。能够像操作变量一样的操作函数这点是*函数式编程*这一非常有趣的程序设计思想的基石之一。 +Scala 中的函数也是对象,所以将函数当做对象传递、把它们存入变量、从其他函数返回函数都是可能的。能够像操作变量一样的操作函数这点是*函数式编程*这一非常有趣的程序设计思想的基石之一。 为何把函数当做变量一样的操作会很有用呢,让我们考虑一个定时函数,功能是每秒执行一些动作。我们要怎么将这动作传给它?最直接的便是将这动作视为函数传入。应该有不少程序员对这种简单传递函数的行为很熟悉:通常在用户界面相关的程序上,用来注册一些当事件发生时被调用的回调函数。 From dbfeb680e2971536dda84e1643fea0ee91df4cad Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Fri, 28 Jun 2019 14:07:09 +0800 Subject: [PATCH 0545/3075] polish. --- _zh-cn/tutorials/scala-for-java-programmers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_zh-cn/tutorials/scala-for-java-programmers.md b/_zh-cn/tutorials/scala-for-java-programmers.md index b5fcb5770e..b42c241852 100644 --- a/_zh-cn/tutorials/scala-for-java-programmers.md +++ b/_zh-cn/tutorials/scala-for-java-programmers.md @@ -87,7 +87,7 @@ Scala 的导入表达式跟 Java 非常像,但更为强大。如第一行, ## 一切都是对象 -Scala 是一个纯粹的面向对象语言,意即包括数字、函数在内的*所有东西*都是对象。这跟 Java 不同,因为 Java 的基本类型 (如 `boolean` 与 `int` ) 和引用类型是有区别的。 +Scala 是一个纯粹的面向对象语言,意即包括数字、函数在内的*一切*都是对象。这跟 Java 不同,因为 Java 的基本类型 (如 `boolean` 与 `int` ) 和引用类型是有区别的。 ### 数字是对象 From 3bdfd8c2554d34573d4e7057a2dc9847ae844d30 Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Fri, 28 Jun 2019 14:39:17 +0800 Subject: [PATCH 0546/3075] Fix internal hashes. --- _zh-cn/glossary/index.md | 87 ++++++++++++++++++++-------------------- 1 file changed, 43 insertions(+), 44 deletions(-) diff --git a/_zh-cn/glossary/index.md b/_zh-cn/glossary/index.md index 79893b5298..60df57c6eb 100644 --- a/_zh-cn/glossary/index.md +++ b/_zh-cn/glossary/index.md @@ -29,7 +29,7 @@ match表达式的一个分支,形如 “`case` _pattern_ => _expression_”。 匿名类是由Scala编译器根据一种new表达式生成的合成子类,这种new表达式由类名或特质名后面紧跟一对花括号组成。花括号内包含了匿名子类的构造体,可为空,不过一旦跟在new后面名称指向的特质或类包含了抽象成员,则这些抽象成员就必须在其匿名子类的构造体内具化,即在花括号内要实现这些成员。 * #### 匿名函数(anonymous function) -[函数字面量](#function-literal)的另一种叫法。 +[函数字面量](#函数字面量function-literal)的另一种叫法。 * #### 应用(apply) 方法、函数或闭包应用于参数,意思是说通过这些实参来调用方法、函数或闭包。 @@ -44,7 +44,7 @@ match表达式的一个分支,形如 “`case` _pattern_ => _expression_”。 在类定义体花括号里面定义的所有附加构造器,其形似名为`this`但无结果类型的方法定义。 * #### 块(block) -被花括号围起来的一个或多个表达式和声明。求值块的时候,块内所有表达式和声明会被顺序处理,然后会返回最后一个表达式的值作为其自身的值。块通常被用来作为构造体,诸如函数、[for表达式](#for-expression)、`while`循环以及其他任何需要把语句组织到一起的地方,都会用到块。更正式点说,块是一个只其副作用和结果值对外可见的封装构造体。因此,类或对象的花括号是不会形成块的,因其内部定义字段和方法均对外可见。这样的花括号形成的是模板。 +被花括号围起来的一个或多个表达式和声明。求值块的时候,块内所有表达式和声明会被顺序处理,然后会返回最后一个表达式的值作为其自身的值。块通常被用来作为构造体,诸如函数、[for表达式](#for表达式for-expression)、`while`循环以及其他任何需要把语句组织到一起的地方,都会用到块。更正式点说,块是一个只其副作用和结果值对外可见的封装构造体。因此,类或对象的花括号是不会形成块的,因其内部定义字段和方法均对外可见。这样的花括号形成的是模板。 * #### 绑定变量(bound variable) 表达式的绑定变量是定义和使用都在表达式内部的变量。例如,在函数字面量表达式`(x: Int) => (x, y)`里面,`x`和`y`都被用到了,但只有`x`被绑定了,因为它在表达式中被定义为一个`Int`变量,并且它也是表达式所描述函数的唯一实参。 @@ -86,10 +86,10 @@ match表达式的一个分支,形如 “`case` _pattern_ => _expression_”。 类是其 _直接子类_ 的直接超类。 * #### 直接超类(direct superclass) -从某个类直接衍生出类或特质,或者说在继承层级结构最接近自己的上层的某个类,这样的类就是直接超类。若类`Child`的可选的extends子句中含有类`Parent`,则`Parent`就是`Child`的直接超类。若`Child`的可选extends子句中含有特质,则特质的直接超类也是`Child`的直接超类。若`Child`没有extends子句,则`AnyRef`就是`Child`的直接超类。若类的直接超类带有类型参数,比如`Child extends Parent[String]`,`Child`的直接超类依旧是`Parent`,而不是`Parent[String]`。另一方面,`Parent[String]`应该叫做`Child`的直接超类型。参见[超类型](#supertype)了解更多关于类和类型间的区别。 +从某个类直接衍生出类或特质,或者说在继承层级结构最接近自己的上层的某个类,这样的类就是直接超类。若类`Child`的可选的extends子句中含有类`Parent`,则`Parent`就是`Child`的直接超类。若`Child`的可选extends子句中含有特质,则特质的直接超类也是`Child`的直接超类。若`Child`没有extends子句,则`AnyRef`就是`Child`的直接超类。若类的直接超类带有类型参数,比如`Child extends Parent[String]`,`Child`的直接超类依旧是`Parent`,而不是`Parent[String]`。另一方面,`Parent[String]`应该叫做`Child`的直接超类型。参见[超类型](#超类型supertype)了解更多关于类和类型间的区别。 * #### 相等性(equality) -在没有条件限制的情况下使用时,_相等性_ 就是`==`所表达的两个值之间的关系。参见[引用相等性](#reference-equality)。 +在没有条件限制的情况下使用时,_相等性_ 就是`==`所表达的两个值之间的关系。参见[引用相等性](#引用相等性reference-equality)。 * #### 存在类型(existential type) 存在类型包含未知类型变量的引用。比如:`Array[T] forSome { type T }`是个存在类型,是`T`的数组,而`T`是某个完全未知的类型,关于`T`唯一能够假定的是它是确定存在的。尽管这个假定很虚,但是至少意味着`Array[T] forSome { type T }`确实是个数组,而不是香蕉什么的东西。 @@ -98,43 +98,43 @@ match表达式的一个分支,形如 “`case` _pattern_ => _expression_”。 任何能够得到结果的Scala代码,也可说成表达式求值为某个结果或结果为某个值。 * #### 过滤器(filter) -[for表达式](#for-expression)中的`if`及跟在其后的布尔表达式。在`for(i <- 1 to 10; if i % 2 == 0)`中,过滤器为"`if i % 2 == 0`"。`if`右边的值就是[过滤器表达式](#filter-expression),也称为守卫。 +[for表达式](#for表达式for-expression)中的`if`及跟在其后的布尔表达式。在`for(i <- 1 to 10; if i % 2 == 0)`中,过滤器为"`if i % 2 == 0`"。`if`右边的值就是[过滤器表达式](#过滤器表达式filter-expression),也称为守卫。 * #### 过滤器表达式(filter expression) -过滤器表达式就是[for表达式](#for-expression)里面跟在`if`后面的布尔表达式。`for( i <- 1 to 10 ; if i % 2 == 0)`的过滤器表达式为"`i % 2 == 0`"。 +过滤器表达式就是[for表达式](#for表达式for-expression)里面跟在`if`后面的布尔表达式。`for( i <- 1 to 10 ; if i % 2 == 0)`的过滤器表达式为"`i % 2 == 0`"。 * #### 头等函数(first-class function) -Scala支持 _头等函数_ ,意味着可以通过函数字面量语法来表达函数。如:`(x: Int) => x + 1`,并且函数可由对象来表达,叫做[函数值](#function-value)。 +Scala支持 _头等函数_ ,意味着可以通过函数字面量语法来表达函数。如:`(x: Int) => x + 1`,并且函数可由对象来表达,叫做[函数值](#函数值function-value)。 * #### for推解式(for comprehension) -_for推解式_ 是[for表达式](#for-expression)的一种,一般用来创建新的集合。对`for`推解式的每次迭代,[yield](#yield)子句都会定义新集合的一个元素。比如:`for (i <- (0 until 2); j <- (2 until 4)) yield (i, j)`将返回集合`Vector((0,2), (0,3), (1,2), (1,3))`。 +_for推解式_ 是[for表达式](#for表达式for-expression)的一种,一般用来创建新的集合。对`for`推解式的每次迭代,[yield](#产生yield)子句都会定义新集合的一个元素。比如:`for (i <- (0 until 2); j <- (2 until 4)) yield (i, j)`将返回集合`Vector((0,2), (0,3), (1,2), (1,3))`。 * #### for表达式(for expression) -_for表达式_ 要么是个[for循环](#for-loop),可以迭代一个或多个集合,要么是个[for推解式](#for-comprehension),可以从一个或多个集合的元素中推解出一个新的集合。`for`表达式建于[生成器](#generator)、[过滤器](#filter)、变量定义和[yield](#yield)子句(针对[for推解式](#for-comprehension))基础之上, +_for表达式_ 要么是个[for循环](#for循环for-loop),可以迭代一个或多个集合,要么是个[for推解式](#for推解式for-comprehension),可以从一个或多个集合的元素中推解出一个新的集合。`for`表达式建于[生成器](#生成器generator)、[过滤器](#过滤器filter)、变量定义和[yield](#产生yield)子句(针对[for推解式](#for推解式for-comprehension))基础之上, * #### for循环(for loop) -_for循环_ 是[for表达式](#for-expression)的一种,一般用来循环迭代一个或多个集合。因为`for`循环返回unit,所以经常被用来产生副作用。比如:`for (i <- 0 until 100) println(i)`打印数字0到99。 +_for循环_ 是[for表达式](#for表达式for-expression)的一种,一般用来循环迭代一个或多个集合。因为`for`循环返回unit,所以经常被用来产生副作用。比如:`for (i <- 0 until 100) println(i)`打印数字0到99。 * #### 自由变量(free variable) 一个表达式的 _自由变量_ 指的是在表达式中使用但不定义在其中的变量。例如,在函数字面量表达式`(x: Int) => (x, y)`中,变量`x`和`y`都被用到了,但只有`y`是自由变量,因其未在表达式中定义。 * #### 函数(function) -_函数_ 可通过一列实参来[调用](#invoke)然后产生结果。函数一般具有参数列表、函数体和结果类型。作为类、特质或单例对象的函数叫做[方法](#method)。定义在其他函数内部的函数叫做[局部函数](#local-function)。结果类型为`Unit`的函数叫做[过程](#procedure)。源码里面的匿名函数叫做[函数字面量](#function-literal)。运行时,函数字面量被实例化为对象,叫做[函数值](#function-value)。 +_函数_ 可通过一列实参来[调用](#调用invoke)然后产生结果。函数一般具有参数列表、函数体和结果类型。作为类、特质或单例对象的函数叫做[方法](#方法method)。定义在其他函数内部的函数叫做[局部函数](#局部函数local-function)。结果类型为`Unit`的函数叫做[过程](#过程procedure)。源码里面的匿名函数叫做[函数字面量](#函数字面量function-literal)。运行时,函数字面量被实例化为对象,叫做[函数值](#函数值function-value)。 * #### 函数字面量(function literal) 在Scala源码中的无名函数,通过函数字面量语法来特别对待。比如:`(x: Int, y: Int) => x + y`。 * #### 函数值(function value) -可以像其他函数一样被调用的函数对象。函数值的类一般是继承了`scala`包中的`FunctionN`(比如`Function0`,`Function1`等)这类特质的其中之一,且在源码中常通过[函数字面量](#function-literal)语法来表示。当函数值的apply方法被调用时就说这个函数值被调用。捕获自由变量的函数值为[闭包](#closure)。 +可以像其他函数一样被调用的函数对象。函数值的类一般是继承了`scala`包中的`FunctionN`(比如`Function0`,`Function1`等)这类特质的其中之一,且在源码中常通过[函数字面量](#函数字面量function-literal)语法来表示。当函数值的apply方法被调用时就说这个函数值被调用。捕获自由变量的函数值为[闭包](#闭包closure)。 * #### 函数式风格(functional style) -_函数式风格_ 编程注重函数和求值结果而非操作发生的顺序。这种风格的特征是可传递函数值给循环方法、不可变数据、方法无副作用,是像Haskell和Erlang等这些语言的主要范式,与[命令式风格](#imperative-style)相对应。 +_函数式风格_ 编程注重函数和求值结果而非操作发生的顺序。这种风格的特征是可传递函数值给循环方法、不可变数据、方法无副作用,是像Haskell和Erlang等这些语言的主要范式,与[命令式风格](#命令式风格imperative-style)相对应。 * #### 生成器(generator) -生成器在[for表达式](#for-expression)中定义一个命名的val变量并赋予其一系列值。比如:`for(i <- 1 to 10)`的生成器是"`i <- 1 to 10`",`<-`右边的值是[generator表达式](#generator-expression)。 +生成器在[for表达式](#for表达式for-expression)中定义一个命名的val变量并赋予其一系列值。比如:`for(i <- 1 to 10)`的生成器是"`i <- 1 to 10`",`<-`右边的值是[生成器表达式](#生成器表达式generator-expression)。 * #### 生成器表达式(generator expression) -生成器表达式在[for表达式](#for-expression)中生成一些列值。比如:`for(i <- 1 to 10)`的生成器表达式是"`1 to 10`"。 +生成器表达式在[for表达式](#for表达式for-expression)中生成一些列值。比如:`for(i <- 1 to 10)`的生成器表达式是"`1 to 10`"。 * #### 泛型类(generic class) 带有类型参数的类。例如,因`scala.List`带一类型参数,故其为泛型类。 @@ -143,19 +143,19 @@ _函数式风格_ 编程注重函数和求值结果而非操作发生的顺序 带有类型参数的特质。例如,因`scala.collection.Set`带一类型参数,故其为泛型特质。 * #### 守卫(guard) -参见[过滤器](#filter). +参见[过滤器](#过滤器filter). * #### 辅助函数(helper function) 目的是为一个或多个其他邻近函数提供服务的函数。辅助函数常实现为局部函数。 * #### 辅助方法(helper method) -作为类成员的[辅助函数](#helper-function)。辅助方法常为私有方法。 +作为类成员的[辅助函数](#辅助函数helper-function)。辅助方法常为私有方法。 * #### 不可变(immutable) 若对象的值在任何对客户端可见的方式下创建后不会被修改则称对象是 _不可变_ 的。对象既可以是不可变的,也可以是可变的。 * #### 命令式风格(imperative style) -_命令式风格_ 编程强调严谨的操作序列以令效用能在正确的顺序发生。这种风格的特征是循环迭代、适当变更数据、方法有副作用,是像C, C++, C#和Java等这些语言的主要范式,与[函数式风格](#functional-style)相对应。 +_命令式风格_ 编程强调严谨的操作序列以令效用能在正确的顺序发生。这种风格的特征是循环迭代、适当变更数据、方法有副作用,是像C, C++, C#和Java等这些语言的主要范式,与[函数式风格](#函数式风格functional-style)相对应。 * #### 初始化(initialize) 变量在Scala源码中被定义时,必须用对象对其进行初始化。 @@ -173,16 +173,16 @@ _不变性_ 用在两个地方。首先在数据结构组织良好的情况下 在实参上 _调用_ 方法、函数或闭包,意即其方法体会在指定实参上执行。 * #### Java虚拟机(JVM) -_JVM_ 是Java虚拟机(#runtime)的缩写,或叫[运行时](#runtime),是运行Scala程序的宿主。 +_JVM_ 是Java虚拟机(#runtime)的缩写,或叫[运行时](#运行时runtime),是运行Scala程序的宿主。 * #### 字面量(literal) `1`,`"One"`,和`(x: Int) => x + 1`是 _字面量_ 的例子,字面量是描述对象的便捷方式,便捷在这种方式正好反映了所创建对象的结构。 * #### 局部函数(local function) -_局部函数_ 是块内`def`定义的,作为对比,同为`def`定义的作为类、特质或单例对象的成员则被称作[方法](#method)。 +_局部函数_ 是块内`def`定义的,作为对比,同为`def`定义的作为类、特质或单例对象的成员则被称作[方法](#方法method)。 * #### 局部变量(local variable) -_局部变量_ 是块内`val`或`var`定义的。尽管函数参数和[局部变量](#local-variable)类似,但并不叫局部变量,而是去掉"局部"直接叫"参数"或"变量"。 +_局部变量_ 是块内`val`或`var`定义的。尽管函数参数和[局部变量](#局部变量local-variable)类似,但并不叫局部变量,而是去掉"局部"直接叫"参数"或"变量"。 * #### 成员(member) _成员_ 是类、特质或单例对象模板中被命名的元素。成员可通过所有者名称,点及其简名访问。例如,定义在类的最顶层字段和方法是这个类的成员。定义在类中的特质是包围它的类的成员。类中通过type关键字定义的类型是这个类的成员。类是其定义所在的包的成员。相比之下,局部变量或局部函数就不是包围他们的块的成员。 @@ -218,7 +218,7 @@ _混入_ 就是特质用在混入组合时的名称。换言之,在"`trait Hat 函数可带有零至多个 _参数_,每个参数都有名称和类型。参数与实参之间的区别在于函数调用时实参指向具体的对象,参数则是指向这些传入实参的变量。 * #### 无参函数(parameterless function) -不带参数的函数,其定义时没有任何空括号。无参函数可不带括号调用,这种方式符合[统一访问原则](#uniform-access-principle),就是在客户端不改变任何代码的情况下把`def`改成`val`。 +不带参数的函数,其定义时没有任何空括号。无参函数可不带括号调用,这种方式符合[统一访问原则](#统一访问原则uniform-access-principle),就是在客户端不改变任何代码的情况下把`def`改成`val`。 * #### 无参方法(parameterless method) _无参方法_ 就是作为类、特质或单例对象成员的无参函数。 @@ -236,7 +236,7 @@ _无参方法_ 就是作为类、特质或单例对象成员的无参函数。 在`match`表达式的某个备选项中,_模式_ 跟在`case`关键字后,先于 _模式守卫_ 或`=>`符号二者之一。 * #### 模式守卫(pattern guard) -在`match`表达式的某个备选项中,_模式守卫_ 可跟在某个[模式](#pattern)后面。比如,"`case x if x % 2 == 0 => x + 1`"中的模式守卫为"`if x % 2 == 0`"。带有模式守卫的备选项(case)仅当其模式匹配了并且模式守卫为真的时候才会被选中。 +在`match`表达式的某个备选项中,_模式守卫_ 可跟在某个[模式](#模式pattern)后面。比如,"`case x if x % 2 == 0 => x + 1`"中的模式守卫为"`if x % 2 == 0`"。带有模式守卫的备选项(case)仅当其模式匹配了并且模式守卫为真的时候才会被选中。 * #### 断言(predicate) 断言是结果类型为`Boolean`的函数。 @@ -251,13 +251,13 @@ _过程_ 是结果类型为`Unit`的函数,其存在的理由仅为产生副 变量可以是可重新赋值的,也可以不是可重新赋值的。`var`是可重新赋值的,而`val`则不是。 * #### 递归的(recursive) -若函数可调用自身就说它是 _递归的_。若函数调用自身的唯一位置是函数的最后一个表达式,则函数是[尾递归的](#tail-recursive) +若函数可调用自身就说它是 _递归的_。若函数调用自身的唯一位置是函数的最后一个表达式,则函数是[尾递归](#尾递归tail-recursive)的。 * #### 引用(reference) -_引用_ 是指针的Java抽象,可唯一确定存在JVM堆中的对象。引用类型变量持有对象的引用,因为引用类型(`AnyRef`的实例)是存在JVM堆上的Java对象实现的。相比之下,值类型变量有时会持有一个(装箱类型的)引用,也有时(当对象表示基础类型值的时候)不会。一般说来,Scala变量[指向](#refers)对象。术语"指向"比"持有引用"更加抽象。如果类型为`scala.Int`的变量当前代表Java基础类型`int`的值,则这个变量仍然指向`Int`对象,但并不涉及任何引用。 +_引用_ 是指针的Java抽象,可唯一确定存在JVM堆中的对象。引用类型变量持有对象的引用,因为引用类型(`AnyRef`的实例)是存在JVM堆上的Java对象实现的。相比之下,值类型变量有时会持有一个(装箱类型的)引用,也有时(当对象表示基础类型值的时候)不会。一般说来,Scala变量[指向](#指向refers)对象。术语"指向"比"持有引用"更加抽象。如果类型为`scala.Int`的变量当前代表Java基础类型`int`的值,则这个变量仍然指向`Int`对象,但并不涉及任何引用。 * #### 引用相等性(reference equality) -_引用相等性_ 意思是两个引用指向同一个Java对象。引用相等性仅针对引用类型有意义,是可以通过调用`AnyRef`中的`eq`来确定的(在Java程序中,引用相等性通过在Java[引用类型](#reference-type)上调用`==`来确定)。 +_引用相等性_ 意思是两个引用指向同一个Java对象。引用相等性仅针对引用类型有意义,是可以通过调用`AnyRef`中的`eq`来确定的(在Java程序中,引用相等性通过在Java[引用类型](#引用类型reference-type)上调用`==`来确定)。 * #### 引用类型(reference type) _引用类型_ 是`AnyRef`的子类。在运行时,引用类型的实例常驻JVM堆中。 @@ -266,7 +266,7 @@ _引用类型_ 是`AnyRef`的子类。在运行时,引用类型的实例常驻 独立于临时上下文且无副作用的函数属性。对于特定输入,引用透明函数的调用可由其结果替换而不改变程序语义。 * #### 指向(refers) -运行的Scala程序中的变量常 _指向_ 某个对象。变量即使被赋为`null`,概念上也是指向`Null`对象。在运行时,对象可由Java对象或基础类型值来实现,不过Scala允许程序员在更高层次抽象代码以他们设想的方式运行。参见[引用](#reference). +运行的Scala程序中的变量常 _指向_ 某个对象。变量即使被赋为`null`,概念上也是指向`Null`对象。在运行时,对象可由Java对象或基础类型值来实现,不过Scala允许程序员在更高层次抽象代码以他们设想的方式运行。参见[引用](#引用reference). * #### 精化类型(refinement type) 通过提供基础类型及其构造体花括号内若干成员而形成的类型。花括号内的成员精细化了基础类型所体现的类型。比如,"食草动物"(animal that eats grass)的类型为`Animal { type SuitableFood = Grass }`。 @@ -279,14 +279,13 @@ Scala程序中的表达式会产生 _结果_。Scala中的每个表达式的结 方法的 _结果类型_ 是调用方法所产生的值的类型。(在Java中,这个概念被称为返回类型) * #### 返回(return) -Scala程序中的函数会 _返回_ 值,可把这个值叫做函数的[结果](#result)。也可以说函数 _结果是_ 某个值。Scala中的每个函数结果都是一个对象。 -A function in a Scala program `returns` a value. You can call this value the [result](#result) of the function. You can also say the function _results in_ the value. The result of every function in Scala is an object. +Scala程序中的函数会 _返回_ 值,可把这个值叫做函数的[结果](#结果result)。也可以说函数 _结果是_ 某个值。Scala中的每个函数结果都是一个对象。 * #### 运行时(runtime) -正在运行Scala程序的宿主Java虚拟机,或宿主[JVM](#jvm)。运行时这个概念包含了Java虚拟机规范中定义的虚拟机以及Java API和标准Scala API的运行时库。在运行时的这个阶段,意味着程序正在运行中,与编译时是相对的概念。 +正在运行Scala程序的宿主Java虚拟机,或宿主[JVM](#java虚拟机jvm)。运行时这个概念包含了Java虚拟机规范中定义的虚拟机以及Java API和标准Scala API的运行时库。在运行时的这个阶段,意味着程序正在运行中,与编译时是相对的概念。 * #### 运行时类型(runtime type) -对象在运行时的类型。相比之下,[静态类型](#static-type)指的是表达式在编译时的类型。多数运行时类型都是无类型参数的裸类,比如,`"Hi"`的运行时类型是`String`,`(x: Int) => x + 1`的运行时类型是`Function1`。运行时类型可通过`isInstanceOf`来检测。 +对象在运行时的类型。相比之下,[静态类型](#静态类型static-type)指的是表达式在编译时的类型。多数运行时类型都是无类型参数的裸类,比如,`"Hi"`的运行时类型是`String`,`(x: Int) => x + 1`的运行时类型是`Function1`。运行时类型可通过`isInstanceOf`来检测。 * #### 脚本(script) 包含顶层定义和语句,可直接通过`scala`命令来跑而无需显式编译的文件就是脚本,脚本结尾必须是表达式,而不能是定义。 @@ -307,28 +306,28 @@ XML数据就是半结构化的,因其相比于普通的二进制文件或文 局部变量的重新声明会 _遮掩_ 作用域内相同名称的变量声明。 * #### 签名(signature) -_签名_ 是[类型签名](#type-signature)的简写。 +_签名_ 是[类型签名](#类型签名type-signature)的简写。 * #### 单例对象(singleton object) -由object关键字定义的对象。每个单例对象有且仅有一个实例。与某个类共享名称且与这个类定义在同一源文件中的单例对象,叫这个类的[伴随对象](#companion-object),类则叫单列对象的[伴随类](#companion-class)。无伴随类的单例对象叫[独立对象](#standalone-object)。 +由object关键字定义的对象。每个单例对象有且仅有一个实例。与某个类共享名称且与这个类定义在同一源文件中的单例对象,叫这个类的[伴随对象](#伴随对象companion-object),类则叫单列对象的[伴随类](#伴随类companion-class)。无伴随类的单例对象叫[独立对象](#独立对象standalone-object)。 * #### 独立对象(standalone object) -没有[伴生类](#companion-class)的[单例对象](#singleton-object)。 +没有[伴生类](#伴生类companion-class)的[单例对象](#单例对象singleton-object)。 * #### 语句(statement) 指的是表达式、定义或包导入等这些可放到Scala源码的模板或块中的东西。 * #### 静态类型(static type) -参见[类型](#type)。 +参见[类型](#类型type)。 * #### 结构类型(structural type) -也是一种[精化类型](#refinement-type),只是精化的目标是未在基类型中的成员。比如`{ def close(): Unit }`就是结构类型,因其基类型是`AnyRef`,而`AnyRef`并无名为`close`的成员。 +也是一种[精化类型](#精化类型refinement-type),只是精化的目标是未在基类型中的成员。比如`{ def close(): Unit }`就是结构类型,因其基类型是`AnyRef`,而`AnyRef`并无名为`close`的成员。 * #### 子类(subclass) -一个类是其所有[超类](#superclass)和[超特质](#supertrait)的 _子类_。 +一个类是其所有[超类](#超类superclass)和[超特质](#超特质supertrait)的 _子类_。 * #### 子特质(subtrait) -一个特质是其所有[超特质](#supertrait)的 _子特质_。 +一个特质是其所有[超特质](#超特质supertrait)的 _子特质_。 * #### 子类型(subtype) Scala编译器允许任何类型在需要该类型的地方使用其 _子类型_ 作为替代。对不带类型参数的类和特质来说,子类型的关系会反映子类的关系。比如,若类`Cat`是抽象类`Animal`的子类,且也不带类型参数,则类型`Cat`就是类型`Animal`的子类型。同样,若特质`Apple`是特质`Fruit`的子特质且无类型参数,则类型`Apple`就是类型`Fruit`的子类型。而对于带有类型参数的类和特质来说,协变就起作用了。比如,由于抽象类`List`被声明为在其长类型参数上是协变的(例,`List`被声明为`List[+A]`),`List[Cat]`是`List[Animal]`的子类型,`List[Apple]`是`List[Fruit]`的子类型。尽管这些类型的类都是`List`,但其子类型的关系依旧是存在的。对比来看,因为`Set`未被声明在其类型参数上是协变的(例,`Set`被声明为`Set[A]`,不带加号),所以`Set[Cat]`并不是`Set[Animal]`的子类型。子类型应该正确实现其超类型的契约,以便应用里氏替换原则(Liskov Substitution Principle),不过编译器仅会在类型检查级别核验此属性。 @@ -355,13 +354,13 @@ _目标类型化_ 是参考所需类型来进行类型推导的一种形式。 _模板_ 是类、特质或单例对象定义体,它定义了类、特质或对象的类型签名,行为以及初始状态。 * #### 特质(trait) -_特质_ 通过`trait`关键字定义,是像抽象类一样不带任何值参数,并且可通过被称为[混入组合](#mixin-composition)的过程"混入到"类或其他特质。当某个特质被混入到其他类或特质,它就被叫做[混入](#mixin)。特质可通过一个或多个类型参数化。用类型来参数化后,特质就形成了类型。比如,`Set`是带有单类型参数的特质,而`Set[Int]`却是一个类型。`Set`也被说成是类型`Set[Int]`的"特质"。 +_特质_ 通过`trait`关键字定义,是像抽象类一样不带任何值参数,并且可通过被称为[混入组合](#混入组合mixin-composition)的过程"混入到"类或其他特质。当某个特质被混入到其他类或特质,它就被叫做[混入](#混入mixin)。特质可通过一个或多个类型参数化。用类型来参数化后,特质就形成了类型。比如,`Set`是带有单类型参数的特质,而`Set[Int]`却是一个类型。`Set`也被说成是类型`Set[Int]`的"特质"。 * #### 类型(type) -Scala程序中每个变量和表达式都有编译时确定的 _类型_。类型可以在运行时限定变量能指向的值和表达式所能产生的值。如果有必要从对象的[运行时类型](#runtime-type)的角度对变量和表达式的类型进行区分的话,他们也被称为 _静态类型_。换句话说,"类型"这个词本身意味着静态类型。类型与类是区分开的因为带有类型参数的类可以构成许多类型。比如,`List`是类不是类型,`List[T]`则是一个带有自由类型参数的类型,`List[Int]`和`List[String]`也是类型(称为实类型因为他们没有自由类型参数)。类型可以有"[类](#class)"或"[特质](#trait)",比如类型`List[Int]`的类是`List`,类型`Set[String]`的特质是`Set`。 +Scala程序中每个变量和表达式都有编译时确定的 _类型_。类型可以在运行时限定变量能指向的值和表达式所能产生的值。如果有必要从对象的[运行时类型](#运行时类型runtime-type)的角度对变量和表达式的类型进行区分的话,他们也被称为 _静态类型_。换句话说,"类型"这个词本身意味着静态类型。类型与类是区分开的因为带有类型参数的类可以构成许多类型。比如,`List`是类不是类型,`List[T]`则是一个带有自由类型参数的类型,`List[Int]`和`List[String]`也是类型(称为实类型因为他们没有自由类型参数)。类型可以有"[类](#类class)"或"[特质](#特质trait)",比如类型`List[Int]`的类是`List`,类型`Set[String]`的特质是`Set`。 * #### 类型约束(type constraint) -有些[注解](#annotation)是 _类型约束_,意味着他们会对类型能够包含的取值增加额外的限制或约束。比如,`@positive`可以是类型`Int`的类型约束,用来限制32位整型的取值为正的整数。类型约束虽然不会被标准Scala编译器检查,但相应的必须可被额外的工具或编译器插件检查。 +有些[注解](#注解annotation)是 _类型约束_,意味着他们会对类型能够包含的取值增加额外的限制或约束。比如,`@positive`可以是类型`Int`的类型约束,用来限制32位整型的取值为正的整数。类型约束虽然不会被标准Scala编译器检查,但相应的必须可被额外的工具或编译器插件检查。 * #### 类型构造器(type constructor) 带类型参数的类或特质。 @@ -379,7 +378,7 @@ _统一访问原则_ 指的是变量和无参函数应以相同的语法来访 在Scala层面,对象可以是 _不可达_ 的,此时其所占据的内存可被运行时回收。不可达并不一定意味着未被引用。引用类型(`AnyRef`的实例)被实现为驻于JVM堆上的对象。当引用类型的实例不可达后,它也确实不被引用了,且可被垃圾回收。值类型(`AnyVal`的实例)可被实现为驻于堆中的基础类型值或Java包装类型实例(如`java.lang.Integer`)。值类型实例可在指向他们的变量的整个生命周期内被装箱(从基础类型值转成包装类型对象)或拆箱(从包装类型对象转成基础类型值)。若表现为JVM堆上的包装类型对象的值类型实例不可达,那就确实不会被引用并且可被垃圾回收。但是若正在表现为基础类型值的值类型不可达,则其仍可被引用,因为此时它并不会以作为对象驻于JVM堆上。运行时可回收不可达对象所占据的内存,但是假如一个Int在运行时被实现为Java基础类型int,在一个运行中的方法的栈帧上占据了一些内存,则这个对象的内存将在方法运行完成且栈帧弹出时才被回收。引用类型的内存,比如`Strings`,可在不可达之后由JVM的垃圾收集器回收。 * #### 未引用(unreferenced) -参见[不可达](#unreachable)。 +参见[不可达](#不可达unreachable)。 * #### 值(value) Scala中的任何计算或表达式的结果都是一个 _值_,而Scala中的每个值都是一个对象。值这个术语本质上是指对象在内存中(在JVM堆或栈上)的镜像。 @@ -391,7 +390,7 @@ _值类型_ 是`AnyVal`的任意子类,像`Int`,`Double`或`Unit`。该术 指向对象的命名实体。变量要么是`val`,要么是 `var`,`val`变量和`var`变量在定义时都必须被初始化,但仅`var`变量可被重新赋值来指向不同对象。 * #### 型变(variance) -类或特质的类型参数可用 _型变_ 标号来做标记,即[协变](#covariant)(+)或[逆变](#contravariant)(-)。这样的型变标号表明了泛型类或特质的子类化是如何开展的,比如,泛型类`List`在其类型参数上是协变的,因此`List[String]`就是`List[Any]`的子类型。默认情况下,即缺少标号`+`或`-`的类型参数是[非协变](#nonvariant)的。 +类或特质的类型参数可用 _型变_ 标号来做标记,即[协变](#协变covariant)(+)或[逆变](#逆变contravariant)(-)。这样的型变标号表明了泛型类或特质的子类化是如何开展的,比如,泛型类`List`在其类型参数上是协变的,因此`List[String]`就是`List[Any]`的子类型。默认情况下,即缺少标号`+`或`-`的类型参数是[非协变](#非协变nonvariant)的。 * #### 产生(yield) -表达式可以 _产生_ 结果。`yield`关键字指定了[for推解式](#for-comprehension)的结果。 +表达式可以 _产生_ 结果。`yield`关键字指定了[for推解式](#for推解式for-comprehension)的结果。 From 72add3cf5f67110884e1243dd5beb973de4b081d Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Fri, 28 Jun 2019 14:53:56 +0800 Subject: [PATCH 0547/3075] Fix typo for internal hashes. --- _zh-cn/glossary/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_zh-cn/glossary/index.md b/_zh-cn/glossary/index.md index 60df57c6eb..393593654d 100644 --- a/_zh-cn/glossary/index.md +++ b/_zh-cn/glossary/index.md @@ -309,7 +309,7 @@ XML数据就是半结构化的,因其相比于普通的二进制文件或文 _签名_ 是[类型签名](#类型签名type-signature)的简写。 * #### 单例对象(singleton object) -由object关键字定义的对象。每个单例对象有且仅有一个实例。与某个类共享名称且与这个类定义在同一源文件中的单例对象,叫这个类的[伴随对象](#伴随对象companion-object),类则叫单列对象的[伴随类](#伴随类companion-class)。无伴随类的单例对象叫[独立对象](#独立对象standalone-object)。 +由object关键字定义的对象。每个单例对象有且仅有一个实例。与某个类共享名称且与这个类定义在同一源文件中的单例对象,叫这个类的[伴生对象](#伴生对象companion-object),类则叫单列对象的[伴生类](#伴生类companion-class)。无伴随类的单例对象叫[独立对象](#独立对象standalone-object)。 * #### 独立对象(standalone object) 没有[伴生类](#伴生类companion-class)的[单例对象](#单例对象singleton-object)。 From 60011d873bfcd15b38e6445ccb51c32de28e9377 Mon Sep 17 00:00:00 2001 From: Anastasia Ostretsova Date: Fri, 28 Jun 2019 20:28:21 +0300 Subject: [PATCH 0548/3075] Translate "Partial application" part into russian --- _ru/tour/multiple-parameter-lists.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/_ru/tour/multiple-parameter-lists.md b/_ru/tour/multiple-parameter-lists.md index d1938cb4b0..f58066b0e8 100644 --- a/_ru/tour/multiple-parameter-lists.md +++ b/_ru/tour/multiple-parameter-lists.md @@ -78,3 +78,20 @@ numbers.foldRight(0)(_+_) // Форма с каррированием def execute(arg: Int)(implicit ec: ExecutionContext) = ??? ``` +#### Частичное применение + Когда метод вызывается с меньшим количеством списков параметров, то результатом будет функция, + которая принимает в качестве параметров недостающие списки. Это официально известно как + [частичное применение](https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5). + + Например, + + ```tut + val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + val numberFunc = numbers.foldLeft(List[Int]()) _ + + val squares = numberFunc((xs, x) => xs :+ x*x) + print(squares) // List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100) + + val cubes = numberFunc((xs, x) => xs :+ x*x*x) + print(cubes) // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000) + ``` \ No newline at end of file From e26fc4b0de48b9e7dee9eb545350c446f0000d49 Mon Sep 17 00:00:00 2001 From: Guannan Wei Date: Fri, 28 Jun 2019 17:08:16 -0400 Subject: [PATCH 0549/3075] update the compiler plugin example to Scala 2.13 --- _overviews/plugins/index.md | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/_overviews/plugins/index.md b/_overviews/plugins/index.md index 3b11e43164..ff9e3ffdc6 100644 --- a/_overviews/plugins/index.md +++ b/_overviews/plugins/index.md @@ -99,11 +99,6 @@ There are several steps to making the plugin. First you need to write and compile the source of the plugin itself. Here is the source code for it: - // IMPORTANT: - // this code was written for Scala 2.8. - // it needs to be updated for Scala 2.12. - // the changes required are modest. - package localhost import scala.tools.nsc @@ -126,11 +121,11 @@ it: def newPhase(_prev: Phase) = new DivByZeroPhase(_prev) class DivByZeroPhase(prev: Phase) extends StdPhase(prev) { override def name = DivByZero.this.name - def apply(unit: CompilationUnit) { + def apply(unit: CompilationUnit): Unit = { for ( tree @ Apply(Select(rcvr, nme.DIV), List(Literal(Constant(0)))) <- unit.body if rcvr.tpe <:< definitions.IntClass.tpe) { - unit.error(tree.pos, "definitely division by zero") + global.reporter.error(tree.pos, "definitely division by zero") } } } @@ -276,11 +271,6 @@ sure you got the help string looking right. Here is a complete plugin that has an option. This plugin has no behavior other than to print out its option. - // IMPORTANT: - // this code was written for Scala 2.8. - // it needs to be updated for Scala 2.12. - // the changes required are modest. - package localhost import scala.tools.nsc @@ -298,7 +288,7 @@ behavior other than to print out its option. var level = 1000000 - override def processOptions(options: List[String], error: String => Unit) { + override def processOptions(options: List[String], error: String => Unit): Unit = { for (option <- options) { if (option.startsWith("level:")) { level = option.substring("level:".length).toInt @@ -313,15 +303,13 @@ behavior other than to print out its option. private object Component extends PluginComponent { val global: Silly.this.global.type = Silly.this.global - val runsAfter = "refchecks" - // Using the Scala Compiler 2.8.x the runsAfter should be written as shown below - // val runsAfter = List[String]("refchecks"); + val runsAfter = List[String]("refchecks"); val phaseName = Silly.this.name def newPhase(_prev: Phase) = new SillyPhase(_prev) class SillyPhase(prev: Phase) extends StdPhase(prev) { override def name = Silly.this.name - def apply(unit: CompilationUnit) { + def apply(unit: CompilationUnit): Unit = { println("Silliness level: " + level) } } From 61cbc3266b2d32e23d689151a4ad53b1e056c57a Mon Sep 17 00:00:00 2001 From: Anastasia Ostretsova Date: Sat, 29 Jun 2019 13:06:37 +0300 Subject: [PATCH 0550/3075] Leave just an example --- _ru/tour/multiple-parameter-lists.md | 33 ++++++++++++---------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/_ru/tour/multiple-parameter-lists.md b/_ru/tour/multiple-parameter-lists.md index f58066b0e8..019f17d77d 100644 --- a/_ru/tour/multiple-parameter-lists.md +++ b/_ru/tour/multiple-parameter-lists.md @@ -15,6 +15,19 @@ previous-page: nested-functions Методы могут объявляться с несколькими списками параметров. При этом когда такой метод вызывается с меньшим количеством списков параметров, это приводит к созданию новой функции, которая ожидает на вход не достающий список параметров. Формально это называется [частичное применение](https://en.wikipedia.org/wiki/Partial_application). +Например, + + ```tut + val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + val numberFunc = numbers.foldLeft(List[Int]()) _ + + val squares = numberFunc((xs, x) => xs :+ x*x) + print(squares) // List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100) + + val cubes = numberFunc((xs, x) => xs :+ x*x*x) + print(cubes) // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000) + ``` + Рассмотрим такие примеры из класса [Traversable](/overviews/collections/trait-traversable.html) коллекции Scala: ``` @@ -76,22 +89,4 @@ numbers.foldRight(0)(_+_) // Форма с каррированием ``` def execute(arg: Int)(implicit ec: ExecutionContext) = ??? -``` - -#### Частичное применение - Когда метод вызывается с меньшим количеством списков параметров, то результатом будет функция, - которая принимает в качестве параметров недостающие списки. Это официально известно как - [частичное применение](https://ru.wikipedia.org/wiki/%D0%A7%D0%B0%D1%81%D1%82%D0%B8%D1%87%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%B8%D0%BC%D0%B5%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5). - - Например, - - ```tut - val numbers = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) - val numberFunc = numbers.foldLeft(List[Int]()) _ - - val squares = numberFunc((xs, x) => xs :+ x*x) - print(squares) // List(1, 4, 9, 16, 25, 36, 49, 64, 81, 100) - - val cubes = numberFunc((xs, x) => xs :+ x*x*x) - print(cubes) // List(1, 8, 27, 64, 125, 216, 343, 512, 729, 1000) - ``` \ No newline at end of file +``` \ No newline at end of file From 2feaa411073aa8d3ca96afad92f8fc00b14ff71c Mon Sep 17 00:00:00 2001 From: Dima Kotobotov Date: Sat, 29 Jun 2019 20:07:32 +0300 Subject: [PATCH 0551/3075] :pencil2: Fixing typos. --- _overviews/collections-2.13/equality.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/collections-2.13/equality.md b/_overviews/collections-2.13/equality.md index 42137a43ca..68f5f4141c 100644 --- a/_overviews/collections-2.13/equality.md +++ b/_overviews/collections-2.13/equality.md @@ -31,4 +31,4 @@ It does not matter for the equality check whether a collection is mutable or imm java.util.NoSuchElementException: key not found: ArrayBuffer(2, 2, 3) -In this example, the selection in the last line will most likely fail because the hash-code of the array `xs` has changed in the second-to-last line. Therefore, the hash-code-based lookup will look at a different place than the one where `xs` was stored. +In this example, the selection in the last line will most likely fail because the hash-code of the array `buf` has changed in the second-to-last line. Therefore, the hash-code-based lookup will look at a different place than the one where `buf` was stored. From f749e02964f2155db205a66c60e1cf6d242a5580 Mon Sep 17 00:00:00 2001 From: Taketo Iseki Date: Mon, 1 Jul 2019 20:14:23 +0900 Subject: [PATCH 0552/3075] translate tour/automatic-closures into Japanese --- _ja/tour/automatic-closures.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/_ja/tour/automatic-closures.md b/_ja/tour/automatic-closures.md index 29ae0a8c00..3bb7fa6935 100644 --- a/_ja/tour/automatic-closures.md +++ b/_ja/tour/automatic-closures.md @@ -1,6 +1,6 @@ --- layout: tour -title: Automatic Type-Dependent Closure Construction +title: 型依存クロージャの自動構築 language: ja discourse: true @@ -8,9 +8,9 @@ discourse: true partof: scala-tour --- -Scala allows parameterless function names as parameters of methods. When such a method is called, the actual parameters for parameterless function names are not evaluated and a nullary function is passed instead which encapsulates the computation of the corresponding parameter (so-called *call-by-name* evaluation). +Scalaはメソッドのパラメータにパラメータを受け取らない関数名が使えます。このようなメソッドが呼び出される時、パラメータを受け取らない関数名は実際に評価されず、代わりに対応するパラメーターの処理をカプセル化した、引数を取らない関数が渡されます(そのため *名前渡し*評価と呼ばれます)。 -The following code demonstrates this mechanism: +以下のコードはこの仕組みを説明しています。 object TargetTest1 extends Application { def whileLoop(cond: => Boolean)(body: => Unit): Unit = @@ -25,11 +25,11 @@ The following code demonstrates this mechanism: } } -The function whileLoop takes two parameters `cond` and `body`. When the function is applied, the actual parameters do not get evaluated. But whenever the formal parameters are used in the body of `whileLoop`, the implicitly created nullary functions will be evaluated instead. Thus, our method `whileLoop` implements a Java-like while-loop with a recursive implementation scheme. +関数 whileLoop は2つのパラメータ`cond`と`body`を受け取ります。関数が適用される時、実際のパラメータは評価されません。しかし形式上のパラメータが`whileLoop`の本体内で使われる度に、暗黙に生成された引数の無い関数が代わりに評価されます。このようにメソッド`whileLoop`はJavaのようなwhileループを再帰的な実装案で実装しています。 -We can combine the use of [infix/postfix operators](operators.html) with this mechanism to create more complex statements (with a nice syntax). +[中置/後置 演算子](operators.html)とこのメカニズムを組み合わせ利用し、より複雑な式を(より良い構文で)が作れます。 -Here is the implementation of a loop-unless statement: +こちらがloop-unless式の実装です。 object TargetTest2 extends Application { def loop(body: => Unit): LoopUnlessCond = @@ -46,9 +46,9 @@ Here is the implementation of a loop-unless statement: i -= 1 } unless (i == 0) } -The `loop` function just accepts a body of a loop and returns an instance of class `LoopUnlessCond` (which encapsulates this body object). Note that the body didn't get evaluated yet. Class `LoopUnlessCond` has a method `unless` which we can use as a *infix operator*. This way, we achieve a quite natural syntax for our new loop: `loop { < stats > } unless ( < cond > )`. +この`loop`関数はループ処理の本体を受け取り、クラス`LoopUnlessCond`(bodyのオブジェクトをカプセル化する)のインスタンスを返すだけです。bodyはまだ評価されていないことに気をつけてください。クラス`LoopUnlessCond`は中置演算子として使えるメソッド`unless`を持ちます。このようにより自然な構文で新しいループ処理`loop { < stats > } unless ( < cond > )`を作れます。 -Here's the output when `TargetTest2` gets executed: +こちらが`TargetTest2`を実行した時の出力です。 i = 10 i = 9 From 7c9abb1eee083ad094cc72b1b15bc656fa41a919 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Mon, 1 Jul 2019 17:17:33 +0200 Subject: [PATCH 0553/3075] =?UTF-8?q?Move=20guides=20of=202.12=E2=80=99s?= =?UTF-8?q?=20collections=20to=20the=20=E2=80=9CLegacy=E2=80=9D=20category?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also remove the Scala version number from the title of the current collection guide. --- _data/overviews.yml | 104 ++++++++++++++++++++++---------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/_data/overviews.yml b/_data/overviews.yml index bfc4c293ed..c84a29131c 100644 --- a/_data/overviews.yml +++ b/_data/overviews.yml @@ -2,7 +2,7 @@ - category: Standard Library description: "Guides and overviews covering the Scala standard library." overviews: - - title: Scala 2.13’s Collections + - title: Scala Collections by: Martin Odersky and Julien Richard-Foy icon: sitemap url: "collections-2.13/introduction.html" @@ -40,68 +40,21 @@ url: "core/collections-migration-213.html" description: "This page describes the main changes for collection users that migrate to Scala 2.13 and shows how to cross-build projects with Scala 2.11 / 2.12 and 2.13." - - title: The Architecture of Scala 2.13’s Collections + - title: The Architecture of Scala Collections icon: sitemap url: "core/architecture-of-scala-213-collections.html" by: Julien Richard-Foy description: "These pages describe the architecture of the collections framework introduced in Scala 2.13. Compared to the Collections API you will find out more about the internal workings of the framework." - - title: Implementing Custom Collections (Scala 2.13) + - title: Implementing Custom Collections icon: building url: "core/custom-collections.html" by: Martin Odersky, Lex Spoon and Julien Richard-Foy description: "In this document you will learn how the collections framework helps you define your own collections in a few lines of code, while reusing the overwhelming part of collection functionality from the framework." - - title: Adding Custom Collection Operations (Scala 2.13) + - title: Adding Custom Collection Operations icon: building url: "core/custom-collection-operations.html" by: Julien Richard-Foy description: "This guide shows how to write operations that can be applied to any collection type and return the same collection type, and how to write operations that can be parameterized by the type of collection to build." - - title: Scala 2.8 to 2.12’s Collections - by: Martin Odersky - icon: sitemap - url: "collections/introduction.html" - description: "Scala's Collection Library." - subdocs: - - title: Introduction - url: "collections/introduction.html" - - title: Mutable and Immutable Collections - url: "collections/overview.html" - - title: Trait Traversable - url: "collections/trait-traversable.html" - - title: Trait Iterable - url: "collections/trait-iterable.html" - - title: The sequence traits Seq, IndexedSeq, and LinearSeq - url: "collections/seqs.html" - - title: Sets - url: "collections/sets.html" - - title: Maps - url: "collections/maps.html" - - title: Concrete Immutable Collection Classes - url: "collections/concrete-immutable-collection-classes.html" - - title: Concrete Mutable Collection Classes - url: "collections/concrete-mutable-collection-classes.html" - - title: Arrays - url: "collections/arrays.html" - - title: Strings - url: "collections/strings.html" - - title: Performance Characteristics - url: "collections/performance-characteristics.html" - - title: Equality - url: "collections/equality.html" - - title: Views - url: "collections/views.html" - - title: Iterators - url: "collections/iterators.html" - - title: Creating Collections From Scratch - url: "collections/creating-collections-from-scratch.html" - - title: Conversions Between Java and Scala Collections - url: "collections/conversions-between-java-and-scala-collections.html" - - title: Migrating from Scala 2.7 - url: "collections/migrating-from-scala-27.html" - - title: The Architecture of Scala 2.8 to 2.12’s Collections - icon: building - url: "core/architecture-of-scala-collections.html" - by: Martin Odersky and Lex Spoon - description: "These pages describe the architecture of the Scala collections framework in detail. Compared to the Collections API you will find out more about the internal workings of the framework. You will also learn how this architecture helps you define your own collections in a few lines of code, while reusing the overwhelming part of collection functionality from the framework." - category: Language description: "Guides and overviews covering features in the Scala language." @@ -303,7 +256,7 @@ - category: Legacy - description: "Guides covering features no longer relevant to recent Scala versions (2.11+)." + description: "Guides covering features no longer relevant to recent Scala versions (2.12+)." overviews: - title: The Scala Actors Migration Guide by: Vojin Jovanovic and Philipp Haller @@ -317,3 +270,50 @@ description: "This guide describes the API of the scala.actors package of Scala 2.8/2.9. The organization follows groups of types that logically belong together. The trait hierarchy is taken into account to structure the individual sections. The focus is on the run-time behavior of the various methods that these traits define, thereby complementing the existing Scaladoc-based API documentation." label-color: "#899295" label-text: deprecated + - title: Scala 2.8 to 2.12’s Collections + by: Martin Odersky + icon: sitemap + url: "collections/introduction.html" + description: "Scala's Collection Library." + subdocs: + - title: Introduction + url: "collections/introduction.html" + - title: Mutable and Immutable Collections + url: "collections/overview.html" + - title: Trait Traversable + url: "collections/trait-traversable.html" + - title: Trait Iterable + url: "collections/trait-iterable.html" + - title: The sequence traits Seq, IndexedSeq, and LinearSeq + url: "collections/seqs.html" + - title: Sets + url: "collections/sets.html" + - title: Maps + url: "collections/maps.html" + - title: Concrete Immutable Collection Classes + url: "collections/concrete-immutable-collection-classes.html" + - title: Concrete Mutable Collection Classes + url: "collections/concrete-mutable-collection-classes.html" + - title: Arrays + url: "collections/arrays.html" + - title: Strings + url: "collections/strings.html" + - title: Performance Characteristics + url: "collections/performance-characteristics.html" + - title: Equality + url: "collections/equality.html" + - title: Views + url: "collections/views.html" + - title: Iterators + url: "collections/iterators.html" + - title: Creating Collections From Scratch + url: "collections/creating-collections-from-scratch.html" + - title: Conversions Between Java and Scala Collections + url: "collections/conversions-between-java-and-scala-collections.html" + - title: Migrating from Scala 2.7 + url: "collections/migrating-from-scala-27.html" + - title: The Architecture of Scala 2.8 to 2.12’s Collections + icon: building + url: "core/architecture-of-scala-collections.html" + by: Martin Odersky and Lex Spoon + description: "These pages describe the architecture of the Scala collections framework in detail. Compared to the Collections API you will find out more about the internal workings of the framework. You will also learn how this architecture helps you define your own collections in a few lines of code, while reusing the overwhelming part of collection functionality from the framework." From 9a29e0c37f857dca7a712fd43b01ba4379b5ef15 Mon Sep 17 00:00:00 2001 From: take2 Date: Wed, 3 Jul 2019 01:09:30 +0900 Subject: [PATCH 0554/3075] Update _ja/tour/automatic-closures.md Co-Authored-By: Masanori Fujita --- _ja/tour/automatic-closures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_ja/tour/automatic-closures.md b/_ja/tour/automatic-closures.md index 3bb7fa6935..3d21d052cd 100644 --- a/_ja/tour/automatic-closures.md +++ b/_ja/tour/automatic-closures.md @@ -8,7 +8,7 @@ discourse: true partof: scala-tour --- -Scalaはメソッドのパラメータにパラメータを受け取らない関数名が使えます。このようなメソッドが呼び出される時、パラメータを受け取らない関数名は実際に評価されず、代わりに対応するパラメーターの処理をカプセル化した、引数を取らない関数が渡されます(そのため *名前渡し*評価と呼ばれます)。 +Scalaはメソッドのパラメータとしてパラメータ無しの関数名を渡せます。そのようなメソッドが呼ばれると、パラメータ無しの関数名は実際に評価されず、代わりに対応するパラメーターの処理をカプセル化した、引数無しの関数が渡されます(いわゆる *名前渡し*評価です)。 以下のコードはこの仕組みを説明しています。 From 35e386e93a6aa6465514fab1f652501c31e6f166 Mon Sep 17 00:00:00 2001 From: take2 Date: Wed, 3 Jul 2019 01:09:55 +0900 Subject: [PATCH 0555/3075] Update _ja/tour/automatic-closures.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 実装案 => 方法 Co-Authored-By: Masanori Fujita --- _ja/tour/automatic-closures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_ja/tour/automatic-closures.md b/_ja/tour/automatic-closures.md index 3d21d052cd..1d190d4cae 100644 --- a/_ja/tour/automatic-closures.md +++ b/_ja/tour/automatic-closures.md @@ -25,7 +25,7 @@ Scalaはメソッドのパラメータとしてパラメータ無しの関数名 } } -関数 whileLoop は2つのパラメータ`cond`と`body`を受け取ります。関数が適用される時、実際のパラメータは評価されません。しかし形式上のパラメータが`whileLoop`の本体内で使われる度に、暗黙に生成された引数の無い関数が代わりに評価されます。このようにメソッド`whileLoop`はJavaのようなwhileループを再帰的な実装案で実装しています。 +関数 whileLoop は2つのパラメータ`cond`と`body`を受け取ります。関数が適用される時、実際のパラメータは評価されません。しかし形式上のパラメータが`whileLoop`の本体内で使われる度に、暗黙に生成された引数の無い関数が代わりに評価されます。このようにメソッド`whileLoop`はJavaのようなwhileループを再帰的な方法で実装しています。 [中置/後置 演算子](operators.html)とこのメカニズムを組み合わせ利用し、より複雑な式を(より良い構文で)が作れます。 From 6a0d6ea2492a0ba551ac9db86277354d4a17be48 Mon Sep 17 00:00:00 2001 From: take2 Date: Wed, 3 Jul 2019 01:10:14 +0900 Subject: [PATCH 0556/3075] Update _ja/tour/automatic-closures.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 不要ながを削除 Co-Authored-By: Masanori Fujita --- _ja/tour/automatic-closures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_ja/tour/automatic-closures.md b/_ja/tour/automatic-closures.md index 1d190d4cae..a12b8e8742 100644 --- a/_ja/tour/automatic-closures.md +++ b/_ja/tour/automatic-closures.md @@ -27,7 +27,7 @@ Scalaはメソッドのパラメータとしてパラメータ無しの関数名 関数 whileLoop は2つのパラメータ`cond`と`body`を受け取ります。関数が適用される時、実際のパラメータは評価されません。しかし形式上のパラメータが`whileLoop`の本体内で使われる度に、暗黙に生成された引数の無い関数が代わりに評価されます。このようにメソッド`whileLoop`はJavaのようなwhileループを再帰的な方法で実装しています。 -[中置/後置 演算子](operators.html)とこのメカニズムを組み合わせ利用し、より複雑な式を(より良い構文で)が作れます。 +[中置/後置 演算子](operators.html)とこのメカニズムを組み合わせ利用し、より複雑な式を(より良い構文で)作れます。 こちらがloop-unless式の実装です。 From 3d67daf99b56fbef8c7dd45d847f23caeec12548 Mon Sep 17 00:00:00 2001 From: take2 Date: Wed, 3 Jul 2019 01:14:37 +0900 Subject: [PATCH 0557/3075] Update _ja/tour/automatic-closures.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bodyは素直に概念の説明にした方が日本語が読みやすい Co-Authored-By: Masanori Fujita --- _ja/tour/automatic-closures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_ja/tour/automatic-closures.md b/_ja/tour/automatic-closures.md index a12b8e8742..0b865b72fd 100644 --- a/_ja/tour/automatic-closures.md +++ b/_ja/tour/automatic-closures.md @@ -46,7 +46,7 @@ Scalaはメソッドのパラメータとしてパラメータ無しの関数名 i -= 1 } unless (i == 0) } -この`loop`関数はループ処理の本体を受け取り、クラス`LoopUnlessCond`(bodyのオブジェクトをカプセル化する)のインスタンスを返すだけです。bodyはまだ評価されていないことに気をつけてください。クラス`LoopUnlessCond`は中置演算子として使えるメソッド`unless`を持ちます。このようにより自然な構文で新しいループ処理`loop { < stats > } unless ( < cond > )`を作れます。 +この`loop`関数はループ処理の本体を受け取り、クラス`LoopUnlessCond`(この処理の本体をカプセル化する)のインスタンスを返すだけです。処理の本体はまだ評価されていないことに気をつけてください。クラス`LoopUnlessCond`は *中置演算子* として使えるメソッド`unless`を持ちます。このように、新しいループ処理: `loop { < stats > } unless ( < cond > )`のとても自然な構文を作れます。 こちらが`TargetTest2`を実行した時の出力です。 From 6e5434acba1e4ca38b33c31ccdad0924052ec17c Mon Sep 17 00:00:00 2001 From: Suraj Gharat Date: Wed, 3 Jul 2019 15:00:49 +0530 Subject: [PATCH 0558/3075] Update futures.md Correcting a statement that incorrectly refers future instead of promise. --- _overviews/core/futures.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_overviews/core/futures.md b/_overviews/core/futures.md index a0eea92daf..9546e86c33 100644 --- a/_overviews/core/futures.md +++ b/_overviews/core/futures.md @@ -841,7 +841,7 @@ for a more precise description of the semantics. ## Promises So far we have only considered `Future` objects created by -asynchronous computations started using the `future` method. +asynchronous computations started using the `Future` method. However, futures can also be created using *promises*. While futures are defined as a type of read-only placeholder object @@ -935,7 +935,7 @@ has not been completed yet (e.g., there are several HTTP requests being executed from several different futures and the client is interested only in the first HTTP response - corresponding to the first future to complete the promise). For these reasons methods `tryComplete`, -`trySuccess` and `tryFailure` exist on future. The client should be +`trySuccess` and `tryFailure` exist on promise. The client should be aware that using these methods results in programs which are not deterministic, but depend on the execution schedule. From 131a53b860396a4f3392b57513eee368aafdecb4 Mon Sep 17 00:00:00 2001 From: "Aaron S. Hawley" Date: Wed, 3 Jul 2019 05:41:16 -0400 Subject: [PATCH 0559/3075] Fix page title for cheatsheet --- _ba/cheatsheets/index.md | 2 +- _fr/cheatsheets/index.md | 2 +- _ja/cheatsheets/index.md | 2 +- _overviews/cheatsheets/index.md | 2 +- _pt-br/cheatsheets/index.md | 2 +- _ru/cheatsheets/index.md | 2 +- _th/cheatsheets/index.md | 2 +- _zh-cn/cheatsheets/index.md | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/_ba/cheatsheets/index.md b/_ba/cheatsheets/index.md index 0a7e59790f..c311bf4b1e 100644 --- a/_ba/cheatsheets/index.md +++ b/_ba/cheatsheets/index.md @@ -1,6 +1,6 @@ --- layout: cheatsheet -title: Scalacheat +title: Scala Cheatsheet partof: cheatsheet diff --git a/_fr/cheatsheets/index.md b/_fr/cheatsheets/index.md index 9cb47c6f8d..a75cc71141 100644 --- a/_fr/cheatsheets/index.md +++ b/_fr/cheatsheets/index.md @@ -1,6 +1,6 @@ --- layout: cheatsheet -title: Scalacheat +title: Scala Cheatsheet partof: cheatsheet diff --git a/_ja/cheatsheets/index.md b/_ja/cheatsheets/index.md index b133ef48e4..cf7d670ced 100644 --- a/_ja/cheatsheets/index.md +++ b/_ja/cheatsheets/index.md @@ -1,6 +1,6 @@ --- layout: cheatsheet -title: Scalacheat +title: Scala Cheatsheet partof: cheatsheet diff --git a/_overviews/cheatsheets/index.md b/_overviews/cheatsheets/index.md index 42c2b9c06b..07d96b55c8 100644 --- a/_overviews/cheatsheets/index.md +++ b/_overviews/cheatsheets/index.md @@ -1,6 +1,6 @@ --- layout: cheatsheet -title: Scalacheat +title: Scala Cheatsheet partof: cheatsheet diff --git a/_pt-br/cheatsheets/index.md b/_pt-br/cheatsheets/index.md index 5d3176bda0..27e64f8d74 100644 --- a/_pt-br/cheatsheets/index.md +++ b/_pt-br/cheatsheets/index.md @@ -1,6 +1,6 @@ --- layout: cheatsheet -title: Scalacheat +title: Scala Cheatsheet partof: cheatsheet diff --git a/_ru/cheatsheets/index.md b/_ru/cheatsheets/index.md index 83d2e9d7c4..98b883f9e4 100644 --- a/_ru/cheatsheets/index.md +++ b/_ru/cheatsheets/index.md @@ -1,6 +1,6 @@ --- layout: cheatsheet -title: Scalacheat +title: Scala Cheatsheet partof: cheatsheet diff --git a/_th/cheatsheets/index.md b/_th/cheatsheets/index.md index 0b2faca68b..26b27062da 100644 --- a/_th/cheatsheets/index.md +++ b/_th/cheatsheets/index.md @@ -1,6 +1,6 @@ --- layout: cheatsheet -title: Scalacheat +title: Scala Cheatsheet partof: cheatsheet diff --git a/_zh-cn/cheatsheets/index.md b/_zh-cn/cheatsheets/index.md index 6fe47a86b2..b8178b3fd3 100644 --- a/_zh-cn/cheatsheets/index.md +++ b/_zh-cn/cheatsheets/index.md @@ -1,6 +1,6 @@ --- layout: cheatsheet -title: Scalacheat +title: Scala Cheatsheet partof: cheatsheet From 7290a257267acbc58ebe6be55df9dea0e6a07062 Mon Sep 17 00:00:00 2001 From: "Aaron S. Hawley" Date: Wed, 3 Jul 2019 06:46:06 -0400 Subject: [PATCH 0560/3075] Add contributing page for Scaladoc Move off of overview page. Mention Dottydoc. --- _overviews/scaladoc/contribute.md | 28 ++++++++++++++++++++++++++++ _overviews/scaladoc/overview.md | 11 ----------- 2 files changed, 28 insertions(+), 11 deletions(-) create mode 100644 _overviews/scaladoc/contribute.md diff --git a/_overviews/scaladoc/contribute.md b/_overviews/scaladoc/contribute.md new file mode 100644 index 0000000000..e7fa785616 --- /dev/null +++ b/_overviews/scaladoc/contribute.md @@ -0,0 +1,28 @@ +--- +layout: multipage-overview +title: Contributing to Scaladoc + +discourse: true + +partof: scaladoc +overview-name: Scaladoc + +num: 5 + +permalink: /overviews/scaladoc/:title.html +--- + +If you are interested in contributing to the API documentation of the Scala +standard library (the documentation generated by Scaladoc), please read +[Generating Scaladoc]({{ site.baseurl }}/overviews/scaladoc/generate.html) and +[Scaladoc for Library Authors]({{ site.baseurl }}/overviews/scaladoc/basics.html) first. + +If you'd like to contribute to the actual Scaladoc documentation generation +tool itself, then please see the +[Hacker Set Up Guide](http://scala-lang.org/contribute/hacker-guide.html#2-set-up) +which covers the steps and workflow necessary work on the Scaladoc tool. + +As of Scala 2.13, the Scaladoc tool is maintained but not actively +developed. Major development of Scaladoc will progress as a part of +Dotty for Scala 3 in the +[Dottydoc](https://dotty.epfl.ch/docs/usage/dottydoc.html) tool. \ No newline at end of file diff --git a/_overviews/scaladoc/overview.md b/_overviews/scaladoc/overview.md index b31aea8ef5..92426fa0bf 100644 --- a/_overviews/scaladoc/overview.md +++ b/_overviews/scaladoc/overview.md @@ -22,14 +22,3 @@ There are three aspects of Scaladoc documentation: - **[Using the Scaladoc interface]({{ site.baseurl }}/overviews/scaladoc/interface.html)** – how to navigate and use generated Scaladoc documentation to learn more about a library. - **[Scaladoc for Library Authors]({{ site.baseurl }}/overviews/scaladoc/for-library-authors.html)** – how to add Scaladoc comments to generate documentation for your library. - **[Generating documentation for your library with Scaladoc]({{ site.baseurl }}/overviews/scaladoc/generate.html)** – how to use Scaladoc to generate documentation for your library. - -### Contributing to Scaladoc - -If you are interested in contributing to the API documentation of the Scala -standard library (the documentation generated by Scaladoc), please read the -[Scaladoc for Library Authors]({{ site.baseurl }}/overviews/scaladoc/basics.html) first. - -If you'd like to contribute to the actual Scaladoc documentation generation -tool itself, then please see the -[Hacker Set Up Guide](http://scala-lang.org/contribute/hacker-guide.html#2_set_up) -which covers the steps and workflow necessary work on the Scaladoc tool. From cb9c19f2f4225fadfc9029bb32335311aa322914 Mon Sep 17 00:00:00 2001 From: Parambir Singh Date: Thu, 4 Jul 2019 16:37:21 -0700 Subject: [PATCH 0561/3075] Update inner-classes.md Explicitly specify `Unit` return type in example code --- _tour/inner-classes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_tour/inner-classes.md b/_tour/inner-classes.md index 172dd03bcd..fd99065542 100644 --- a/_tour/inner-classes.md +++ b/_tour/inner-classes.md @@ -21,7 +21,7 @@ To illustrate the difference, we quickly sketch the implementation of a graph da class Graph { class Node { var connectedNodes: List[Node] = Nil - def connectTo(node: Node) { + def connectTo(node: Node): Unit = { if (connectedNodes.find(node.equals).isEmpty) { connectedNodes = node :: connectedNodes } @@ -65,7 +65,7 @@ The type `graph1.Node` is distinct from the type `graph2.Node`. In Java, the las class Graph { class Node { var connectedNodes: List[Graph#Node] = Nil - def connectTo(node: Graph#Node) { + def connectTo(node: Graph#Node): Unit = { if (connectedNodes.find(node.equals).isEmpty) { connectedNodes = node :: connectedNodes } From edce11e76d7c3599d78d4d6b11aa89d40c530f03 Mon Sep 17 00:00:00 2001 From: take2 Date: Fri, 5 Jul 2019 12:51:56 +0900 Subject: [PATCH 0562/3075] Update _ja/tour/automatic-closures.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 「代わりに」の意味を明確にするため句点を追加 Co-Authored-By: TATSUNO Yasuhiro --- _ja/tour/automatic-closures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_ja/tour/automatic-closures.md b/_ja/tour/automatic-closures.md index 0b865b72fd..e40a3202fd 100644 --- a/_ja/tour/automatic-closures.md +++ b/_ja/tour/automatic-closures.md @@ -8,7 +8,7 @@ discourse: true partof: scala-tour --- -Scalaはメソッドのパラメータとしてパラメータ無しの関数名を渡せます。そのようなメソッドが呼ばれると、パラメータ無しの関数名は実際に評価されず、代わりに対応するパラメーターの処理をカプセル化した、引数無しの関数が渡されます(いわゆる *名前渡し*評価です)。 +Scalaはメソッドのパラメータとしてパラメータ無しの関数名を渡せます。そのようなメソッドが呼ばれると、パラメータ無しの関数名は実際に評価されず、代わりに、対応するパラメーターの処理をカプセル化した、引数無しの関数が渡されます(いわゆる *名前渡し*評価です)。 以下のコードはこの仕組みを説明しています。 From c8441a92ed310a6d37c128fadb58ca7df8ab7b9e Mon Sep 17 00:00:00 2001 From: take2 Date: Fri, 5 Jul 2019 12:55:56 +0900 Subject: [PATCH 0563/3075] Update _ja/tour/automatic-closures.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit statementは「式」ではなく「文」、文章の流れ的に「命令文」がより適切 Co-Authored-By: TATSUNO Yasuhiro --- _ja/tour/automatic-closures.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_ja/tour/automatic-closures.md b/_ja/tour/automatic-closures.md index e40a3202fd..3b38e98178 100644 --- a/_ja/tour/automatic-closures.md +++ b/_ja/tour/automatic-closures.md @@ -27,7 +27,7 @@ Scalaはメソッドのパラメータとしてパラメータ無しの関数名 関数 whileLoop は2つのパラメータ`cond`と`body`を受け取ります。関数が適用される時、実際のパラメータは評価されません。しかし形式上のパラメータが`whileLoop`の本体内で使われる度に、暗黙に生成された引数の無い関数が代わりに評価されます。このようにメソッド`whileLoop`はJavaのようなwhileループを再帰的な方法で実装しています。 -[中置/後置 演算子](operators.html)とこのメカニズムを組み合わせ利用し、より複雑な式を(より良い構文で)作れます。 +[中置/後置 演算子](operators.html)とこのメカニズムを組み合わせて利用し、より複雑な命令文を(より良い構文で)作れます。 こちらがloop-unless式の実装です。 From 99ce16089c0874e4eba958cbcadb67f59533e442 Mon Sep 17 00:00:00 2001 From: Dima Kotobotov Date: Fri, 5 Jul 2019 00:34:44 +0300 Subject: [PATCH 0564/3075] :pencil2: Fixing typos. --- _overviews/collections-2.13/iterators.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_overviews/collections-2.13/iterators.md b/_overviews/collections-2.13/iterators.md index 55de58cb7e..7577377bb8 100644 --- a/_overviews/collections-2.13/iterators.md +++ b/_overviews/collections-2.13/iterators.md @@ -46,7 +46,7 @@ The other operations that `Iterator` has in common with `Iterable` have the same res4: Boolean = false As you can see, after the call to `it.map`, the `it` iterator hasn’t advanced to its end, but traversing the iterator -resulting from the call to `it.map` also traverses `it` and advances it to its end. +resulting from the call to `res1.foreach` also traverses `it` and advances it to its end. Another example is the `dropWhile` method, which can be used to find the first elements of an iterator that has a certain property. For instance, to find the first word in the iterator above that has at least two characters you could write: @@ -92,7 +92,7 @@ All operations on iterators are summarized below. | **Variations:** | | | `it.buffered` | A buffered iterator returning all elements of `it`. | | `it grouped size` | An iterator that yields the elements returned by `it` in fixed-sized sequence "chunks". | -| `xs sliding size` | An iterator that yields the elements returned by `it` in sequences representing a sliding fixed-sized window. | +| `it sliding size` | An iterator that yields the elements returned by `it` in sequences representing a sliding fixed-sized window. | | **Duplication:** | | | `it.duplicate` | A pair of iterators that each independently return all elements of `it`. | | **Additions:** | | @@ -100,7 +100,7 @@ All operations on iterators are summarized below. | `it.padTo(len, x)` | The iterator that first returns all elements of `it` and then follows that by copies of `x` until length `len` elements are returned overall. | | **Maps:** | | | `it map f` | The iterator obtained from applying the function `f` to every element returned from `it`. | -| `it flatMap f` | The iterator obtained from applying the iterator-valued function f to every element in `it` and appending the results. | +| `it flatMap f` | The iterator obtained from applying the iterator-valued function `f` to every element in `it` and appending the results. | | `it collect f` | The iterator obtained from applying the partial function `f` to every element in `it` for which it is defined and collecting the results. | | **Conversions:** | | | `it.toArray` | Collects the elements returned by `it` in an array. | @@ -118,7 +118,7 @@ All operations on iterators are summarized below. | `it.nonEmpty` | Test whether the collection contains elements (alias of `hasNext`). | | `it.size` | The number of elements returned by `it`. Note: `it` will be at its end after this operation! | | `it.length` | Same as `it.size`. | -| `xs.knownSize` |The number of elements, if this one is known without modifying the iterator’s state, otherwise `-1`. | +| `it.knownSize` |The number of elements, if this one is known without modifying the iterator’s state, otherwise `-1`. | | **Element Retrieval Index Search:**| | | `it find p` | An option containing the first element returned by `it` that satisfies `p`, or `None` is no element qualifies. Note: The iterator advances to after the element, or, if none is found, to the end. | | `it indexOf x` | The index of the first element returned by `it` that equals `x`. Note: The iterator advances past the position of this element. | @@ -157,7 +157,7 @@ All operations on iterators are summarized below. | **Update:** | | | `it.patch(i, jt, r)` | The iterator resulting from `it` by replacing `r` elements starting with `i` by the patch iterator `jt`. | | **Comparison:** | | -| `it sameElements jt` | A test whether iterators it and `jt` return the same elements in the same order. Note: Using the iterators after this operation is undefined and subject to change. | +| `it sameElements jt` | A test whether iterators `it` and `jt` return the same elements in the same order. Note: Using the iterators after this operation is undefined and subject to change. | | **Strings:** | | | `it.addString(b, start, sep, end)`| Adds a string to `StringBuilder` `b` which shows all elements returned by `it` between separators `sep` enclosed in strings `start` and `end`. `start`, `sep`, `end` are all optional. | | `it.mkString(start, sep, end)` | Converts the collection to a string which shows all elements returned by `it` between separators `sep` enclosed in strings `start` and `end`. `start`, `sep`, `end` are all optional. | From b24c5b23f55a03608d46848623eb2ff0f3575605 Mon Sep 17 00:00:00 2001 From: Philippus Date: Sun, 7 Jul 2019 17:36:40 +0200 Subject: [PATCH 0565/3075] Remove redirect_from from ja tour --- _ja/tour/abstract-type-members.md | 2 -- _ja/tour/annotations.md | 1 - _ja/tour/basics.md | 1 - _ja/tour/by-name-parameters.md | 1 - _ja/tour/case-classes.md | 1 - _ja/tour/classes.md | 1 - _ja/tour/compound-types.md | 1 - _ja/tour/default-parameter-values.md | 1 - _ja/tour/extractor-objects.md | 1 - _ja/tour/for-comprehensions.md | 1 - _ja/tour/generic-classes.md | 1 - _ja/tour/higher-order-functions.md | 1 - _ja/tour/implicit-conversions.md | 1 - _ja/tour/implicit-parameters.md | 1 - _ja/tour/inner-classes.md | 1 - _ja/tour/lower-type-bounds.md | 1 - _ja/tour/mixin-class-composition.md | 1 - _ja/tour/multiple-parameter-lists.md | 1 - _ja/tour/named-arguments.md | 1 - _ja/tour/nested-functions.md | 1 - _ja/tour/operators.md | 1 - _ja/tour/pattern-matching.md | 1 - _ja/tour/polymorphic-methods.md | 1 - _ja/tour/regular-expression-patterns.md | 1 - _ja/tour/self-types.md | 1 - _ja/tour/singleton-objects.md | 1 - _ja/tour/tour-of-scala.md | 1 - _ja/tour/traits.md | 1 - _ja/tour/tuples.md | 1 - _ja/tour/unified-types.md | 1 - _ja/tour/upper-type-bounds.md | 1 - _ja/tour/variances.md | 1 - 32 files changed, 33 deletions(-) diff --git a/_ja/tour/abstract-type-members.md b/_ja/tour/abstract-type-members.md index f5821a7b74..0a0a61f387 100644 --- a/_ja/tour/abstract-type-members.md +++ b/_ja/tour/abstract-type-members.md @@ -12,8 +12,6 @@ previous-page: inner-classes topics: abstract type members prerequisite-knowledge: variance, upper-type-bound -redirect_from: "/tutorials/tour/abstract-types.html" -redirect_from: "/tour/abstract-types.html" --- トレイトや抽象クラスのような抽象型は抽象型メンバーを持つことができます。 diff --git a/_ja/tour/annotations.md b/_ja/tour/annotations.md index 88114954f1..5858105b01 100644 --- a/_ja/tour/annotations.md +++ b/_ja/tour/annotations.md @@ -11,7 +11,6 @@ num: 32 next-page: default-parameter-values previous-page: by-name-parameters -redirect_from: "/tutorials/tour/annotations.html" --- アノテーションはメタ情報と定義を関連づけます。例えば、メソッドの前のアノテーション`@deprecated`はメソッドが使われたらコンパイラに警告を出力させます。 diff --git a/_ja/tour/basics.md b/_ja/tour/basics.md index b14330f2b3..8eb67a0ddb 100644 --- a/_ja/tour/basics.md +++ b/_ja/tour/basics.md @@ -11,7 +11,6 @@ num: 2 next-page: unified-types previous-page: tour-of-scala -redirect_from: "/tutorials/tour/basics.html" --- このページでは、Scalaの基本を取り扱います。 diff --git a/_ja/tour/by-name-parameters.md b/_ja/tour/by-name-parameters.md index 86325795ba..411afa5957 100644 --- a/_ja/tour/by-name-parameters.md +++ b/_ja/tour/by-name-parameters.md @@ -11,7 +11,6 @@ num: 31 next-page: annotations previous-page: operators -redirect_from: "/tutorials/tour/by-name-parameters.html" --- *名前渡しのパラメータ*は使用された時に評価されます。それらは*値渡しパラメータ*とは対照的です。名前渡しのパラメータを作るには、単純に`=>`を型の前につけます。 diff --git a/_ja/tour/case-classes.md b/_ja/tour/case-classes.md index 99a1b6e6f0..5493a00790 100644 --- a/_ja/tour/case-classes.md +++ b/_ja/tour/case-classes.md @@ -12,7 +12,6 @@ next-page: pattern-matching previous-page: multiple-parameter-lists prerequisite-knowledge: classes, basics, mutability -redirect_from: "/tutorials/tour/case-classes.html" --- ケースクラスはこれから論じるいくつかの差異はあるものの普通のクラスと似ています。 diff --git a/_ja/tour/classes.md b/_ja/tour/classes.md index 0253f210f5..36cf3ec851 100644 --- a/_ja/tour/classes.md +++ b/_ja/tour/classes.md @@ -13,7 +13,6 @@ previous-page: unified-types topics: classes prerequisite-knowledge: no-return-keyword, type-declaration-syntax, string-interpolation, procedures -redirect_from: "/tutorials/tour/classes.html" --- Scalaにおけるクラスはオブジェクトを作るための設計図です。 diff --git a/_ja/tour/compound-types.md b/_ja/tour/compound-types.md index 6eeadc481d..061a5dc331 100644 --- a/_ja/tour/compound-types.md +++ b/_ja/tour/compound-types.md @@ -11,7 +11,6 @@ num: 24 next-page: self-types previous-page: abstract-type-members -redirect_from: "/tutorials/tour/compound-types.html" --- ときどき、あるオブジェクトの型が、複数の他の型のサブタイプであると表現する必要が生じます。 Scalaでは、これは*複合型*を用いて表現できます。複合型とはオブジェクトの型同士を重ねることです。 diff --git a/_ja/tour/default-parameter-values.md b/_ja/tour/default-parameter-values.md index fe2da78c75..dde76cdeaf 100644 --- a/_ja/tour/default-parameter-values.md +++ b/_ja/tour/default-parameter-values.md @@ -12,7 +12,6 @@ next-page: named-arguments previous-page: annotations prerequisite-knowledge: named-arguments, function syntax -redirect_from: "/tutorials/tour/default-parameter-values.html" --- Scalaはパラメータのデフォルト値を与えることができ、呼び出す側はこれらのパラメータを省略できます。 diff --git a/_ja/tour/extractor-objects.md b/_ja/tour/extractor-objects.md index 2b12283764..d3af5a18e7 100644 --- a/_ja/tour/extractor-objects.md +++ b/_ja/tour/extractor-objects.md @@ -11,7 +11,6 @@ num: 16 next-page: for-comprehensions previous-page: regular-expression-patterns -redirect_from: "/tutorials/tour/extractor-objects.html" --- 抽出子オブジェクトは`unapply`メソッドを持つオブジェクトです。 diff --git a/_ja/tour/for-comprehensions.md b/_ja/tour/for-comprehensions.md index 89bce4d42a..eccd124c8c 100644 --- a/_ja/tour/for-comprehensions.md +++ b/_ja/tour/for-comprehensions.md @@ -11,7 +11,6 @@ num: 17 next-page: generic-classes previous-page: extractor-objects -redirect_from: "/tutorials/tour/for-comprehensions.html" --- Scalaは*シーケンス内包表記*を表現するための軽量な記法を提供します。 diff --git a/_ja/tour/generic-classes.md b/_ja/tour/generic-classes.md index 2535e31695..7912d2be21 100644 --- a/_ja/tour/generic-classes.md +++ b/_ja/tour/generic-classes.md @@ -12,7 +12,6 @@ next-page: variances previous-page: for-comprehensions assumed-knowledge: classes unified-types -redirect_from: "/tutorials/tour/generic-classes.html" --- ジェネリッククラスはパラメータとして型を1つ受け取るクラスです。それらはコレクションクラスで特に役立ちます。 diff --git a/_ja/tour/higher-order-functions.md b/_ja/tour/higher-order-functions.md index 57714202e8..88d432aaf5 100644 --- a/_ja/tour/higher-order-functions.md +++ b/_ja/tour/higher-order-functions.md @@ -11,7 +11,6 @@ num: 8 next-page: nested-functions previous-page: mixin-class-composition -redirect_from: "/tutorials/tour/higher-order-functions.html" --- 高階関数は他の関数をパラメーターとして受け取る、もしくは結果として関数を返します。 diff --git a/_ja/tour/implicit-conversions.md b/_ja/tour/implicit-conversions.md index 386ed3c500..107979e2dc 100644 --- a/_ja/tour/implicit-conversions.md +++ b/_ja/tour/implicit-conversions.md @@ -11,7 +11,6 @@ num: 27 next-page: polymorphic-methods previous-page: implicit-parameters -redirect_from: "/tutorials/tour/implicit-conversions.html" --- 型`S`から型`T`への暗黙の変換は`S => T`という型のimplicit値や、その型に一致するimplicitメソッドで定義されます。 diff --git a/_ja/tour/implicit-parameters.md b/_ja/tour/implicit-parameters.md index 38067f9e27..53613be8ee 100644 --- a/_ja/tour/implicit-parameters.md +++ b/_ja/tour/implicit-parameters.md @@ -11,7 +11,6 @@ num: 26 next-page: implicit-conversions previous-page: self-types -redirect_from: "/tutorials/tour/implicit-parameters.html" --- メソッドは _暗黙の_ パラメータのリストを持つことができ、パラメータリストの先頭には _implicit_ キーワードで印をつけます。 diff --git a/_ja/tour/inner-classes.md b/_ja/tour/inner-classes.md index 4bc373d8c8..03450fdc14 100644 --- a/_ja/tour/inner-classes.md +++ b/_ja/tour/inner-classes.md @@ -11,7 +11,6 @@ num: 22 next-page: abstract-type-members previous-page: lower-type-bounds -redirect_from: "/tutorials/tour/inner-classes.html" --- Scalaではクラスが他のクラスをメンバーとして保持することが可能です。 diff --git a/_ja/tour/lower-type-bounds.md b/_ja/tour/lower-type-bounds.md index d461e31e5d..b6b98cebdb 100644 --- a/_ja/tour/lower-type-bounds.md +++ b/_ja/tour/lower-type-bounds.md @@ -12,7 +12,6 @@ next-page: inner-classes previous-page: upper-type-bounds prerequisite-knowledge: upper-type-bounds, generics, variance -redirect_from: "/tutorials/tour/lower-type-bounds.html" --- [上限型境界](upper-type-bounds.html) は型を別の型のサブタイプに制限しますが、*下限型境界*は型が別の型のスーパータイプであることを宣言します。表現`B >: A`はパラメータ`B`または抽象型`B`が型`A`のスーパータイプであることを表します。ほとんどのケースで`A`はそのクラスの型パラメータであり、`B`はメソッドの型パラメータになります。 diff --git a/_ja/tour/mixin-class-composition.md b/_ja/tour/mixin-class-composition.md index 9ec9fd65f4..c5d40ebe16 100644 --- a/_ja/tour/mixin-class-composition.md +++ b/_ja/tour/mixin-class-composition.md @@ -12,7 +12,6 @@ next-page: higher-order-functions previous-page: tuples prerequisite-knowledge: inheritance, traits, abstract-classes, unified-types -redirect_from: "/tutorials/tour/mixin-class-composition.html" --- ミックスインはクラスを構成するのに使われるトレイトです。 diff --git a/_ja/tour/multiple-parameter-lists.md b/_ja/tour/multiple-parameter-lists.md index a35bccf615..3cddffe859 100644 --- a/_ja/tour/multiple-parameter-lists.md +++ b/_ja/tour/multiple-parameter-lists.md @@ -11,7 +11,6 @@ num: 10 next-page: case-classes previous-page: nested-functions -redirect_from: "/tutorials/tour/multiple-parameter-lists.html" --- メソッドは複数のパラメータリストを持てます。 diff --git a/_ja/tour/named-arguments.md b/_ja/tour/named-arguments.md index b7f0ca82a2..eda94a0c8c 100644 --- a/_ja/tour/named-arguments.md +++ b/_ja/tour/named-arguments.md @@ -12,7 +12,6 @@ next-page: packages-and-imports previous-page: default-parameter-values prerequisite-knowledge: function-syntax -redirect_from: "/tutorials/tour/named-arguments.html" --- メソッドを呼ぶ時、以下のように引数にパラメータ名でラベル付が可能です。 diff --git a/_ja/tour/nested-functions.md b/_ja/tour/nested-functions.md index 05a57a2fae..2769c20674 100644 --- a/_ja/tour/nested-functions.md +++ b/_ja/tour/nested-functions.md @@ -11,7 +11,6 @@ num: 9 next-page: multiple-parameter-lists previous-page: higher-order-functions -redirect_from: "/tutorials/tour/nested-functions.html" --- Scalaではメソッドの定義をネストする(_訳注:入れ子にする_)ことができます。 diff --git a/_ja/tour/operators.md b/_ja/tour/operators.md index b61b229558..e6c2352ef2 100644 --- a/_ja/tour/operators.md +++ b/_ja/tour/operators.md @@ -12,7 +12,6 @@ next-page: by-name-parameters previous-page: type-inference prerequisite-knowledge: case-classes -redirect_from: "/tutorials/tour/operators.html" --- Scalaでは演算子はメソッドです。パラメータを1つだけ持つメソッドであれば*中置演算子*として使えます。例えば、`+`はドット記法で呼び出せます。 diff --git a/_ja/tour/pattern-matching.md b/_ja/tour/pattern-matching.md index d44d13e41b..dd032ed48e 100644 --- a/_ja/tour/pattern-matching.md +++ b/_ja/tour/pattern-matching.md @@ -13,7 +13,6 @@ next-page: singleton-objects previous-page: case-classes prerequisite-knowledge: case-classes, string-interpolation, subtyping -redirect_from: "/tutorials/tour/pattern-matching.html" --- パターンマッチングは値をパターンに照合するための仕組みです。 diff --git a/_ja/tour/polymorphic-methods.md b/_ja/tour/polymorphic-methods.md index 0770657246..7eac75ff39 100644 --- a/_ja/tour/polymorphic-methods.md +++ b/_ja/tour/polymorphic-methods.md @@ -13,7 +13,6 @@ next-page: type-inference previous-page: implicit-conversions prerequisite-knowledge: unified-types -redirect_from: "/tutorials/tour/polymorphic-methods.html" --- Scalaのメソッドは値と同様に型によってパラメータ化することができます。構文はジェネリッククラスの構文と似ています。 diff --git a/_ja/tour/regular-expression-patterns.md b/_ja/tour/regular-expression-patterns.md index 21068d1de1..a81168544c 100644 --- a/_ja/tour/regular-expression-patterns.md +++ b/_ja/tour/regular-expression-patterns.md @@ -12,7 +12,6 @@ num: 15 next-page: extractor-objects previous-page: singleton-objects -redirect_from: "/tutorials/tour/regular-expression-patterns.html" --- 正規表現はデータの中からパターン(またはその欠如)を探すために使うことができる文字列です。 どんな文字列も`.r`メソッドを使うことで、正規表現に変換できます。 diff --git a/_ja/tour/self-types.md b/_ja/tour/self-types.md index 836e4459ec..1bffbfe63c 100644 --- a/_ja/tour/self-types.md +++ b/_ja/tour/self-types.md @@ -13,7 +13,6 @@ previous-page: compound-types topics: self-types prerequisite-knowledge: nested-classes, mixin-class-composition -redirect_from: "/tutorials/tour/self-types.html" --- 自分型は、直接継承していなくてもトレイトが他のトレイトにミックスインされていることを宣言する方法です。 これにより依存先のメンバーをimportなしで利用できます。 diff --git a/_ja/tour/singleton-objects.md b/_ja/tour/singleton-objects.md index e920e884c9..feea0e5171 100644 --- a/_ja/tour/singleton-objects.md +++ b/_ja/tour/singleton-objects.md @@ -11,7 +11,6 @@ num: 13 next-page: regular-expression-patterns previous-page: pattern-matching -redirect_from: "/tutorials/tour/singleton-objects.html" prerequisite-knowledge: classes, methods, private-methods, packages, option --- オブジェクトは丁度1つのインスタンスを持つクラスです。 diff --git a/_ja/tour/tour-of-scala.md b/_ja/tour/tour-of-scala.md index 775c66557f..46658101bf 100644 --- a/_ja/tour/tour-of-scala.md +++ b/_ja/tour/tour-of-scala.md @@ -11,7 +11,6 @@ num: 1 next-page: basics -redirect_from: "/tutorials/tour/tour-of-scala.html" --- ## ようこそツアーへ diff --git a/_ja/tour/traits.md b/_ja/tour/traits.md index 1ea0b11809..5152af0fb0 100644 --- a/_ja/tour/traits.md +++ b/_ja/tour/traits.md @@ -13,7 +13,6 @@ previous-page: classes topics: traits prerequisite-knowledge: expressions, classes, generics, objects, companion-objects -redirect_from: "/tutorials/tour/traits.html" --- トレイトはクラス間でインターフェースとフィールドを共有するために使います。それらはJava 8のインターフェースと似ています。 diff --git a/_ja/tour/tuples.md b/_ja/tour/tuples.md index 0d67f6c5c1..822a6f5a72 100644 --- a/_ja/tour/tuples.md +++ b/_ja/tour/tuples.md @@ -12,7 +12,6 @@ next-page: mixin-class-composition previous-page: traits topics: tuples -redirect_from: "/tutorials/tour/tuples.html" --- Scalaではタプルは決まった数の要素を含む値であり、各要素はそれぞれの型を持ちます。 diff --git a/_ja/tour/unified-types.md b/_ja/tour/unified-types.md index 98482b1c95..c694663c59 100644 --- a/_ja/tour/unified-types.md +++ b/_ja/tour/unified-types.md @@ -12,7 +12,6 @@ next-page: classes previous-page: basics prerequisite-knowledge: classes, basics -redirect_from: "/tutorials/tour/unified-types.html" --- Scalaでは数値や関数を含め、全ての値は型を持ちます。 以下の図は型階層の一部を説明しています。 diff --git a/_ja/tour/upper-type-bounds.md b/_ja/tour/upper-type-bounds.md index 427dbe429f..ac6b1f2440 100644 --- a/_ja/tour/upper-type-bounds.md +++ b/_ja/tour/upper-type-bounds.md @@ -11,7 +11,6 @@ num: 20 next-page: lower-type-bounds previous-page: variances -redirect_from: "/tutorials/tour/upper-type-bounds.html" --- Scalaでは [型パラメータ](generic-classes.html)と[抽象型メンバー](abstract-type-members.html) は型境界による制約をかけることができます。 diff --git a/_ja/tour/variances.md b/_ja/tour/variances.md index 35f0d01de8..523820403f 100644 --- a/_ja/tour/variances.md +++ b/_ja/tour/variances.md @@ -11,7 +11,6 @@ num: 19 next-page: upper-type-bounds previous-page: generic-classes -redirect_from: "/tutorials/tour/variances.html" --- 変位指定は複合型の間の継承関係とそれらの型パラメータ間の継承関係の相関です。 From 4f0e54b1000e155cdd8d1ba3e6de7d7bd02eb933 Mon Sep 17 00:00:00 2001 From: Dale Wijnand Date: Thu, 4 Jul 2019 18:16:59 +0100 Subject: [PATCH 0566/3075] Tweak literal types spec part about asInstanceOf --- _sips/sips/2014-06-27-42.type.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/_sips/sips/2014-06-27-42.type.md b/_sips/sips/2014-06-27-42.type.md index afe0aeaeae..701c01c43c 100644 --- a/_sips/sips/2014-06-27-42.type.md +++ b/_sips/sips/2014-06-27-42.type.md @@ -23,6 +23,7 @@ Sabin** | Feb 9th 2017 | New author volunteered to update the SIP for review | | Nov 16th 2017 | Updated following implementation experience in Typelevel Scala | | Aug 7th 2018 | Updated to remove Symbol literals, which won't be supported in 3 | +| Jul 4th 2019 | Drop behaviour spec around asInstanceOf, which is a user assertion | ## Introduction @@ -104,7 +105,7 @@ Lightbend Scala compiler. narrow(23) // result is 23: 23 ``` -+ Pattern matching against literal types and `isInstanceOf`/`asInstanceOf` tests/conversions are ++ Pattern matching against literal types and `isInstanceOf` tests are implemented via equality/identity tests of the corresponding values. ``` (1: Any) match { @@ -112,8 +113,6 @@ Lightbend Scala compiler. case _ => false } // result is true (1: Any).isInstanceOf[1] // result is true - (1: Any).asInstanceOf[1] // result is 1: 1 - (1: Any).asInstanceOf[2] // ClassCastException ``` + A `scala.ValueOf[T]` type class and corresponding `scala.Predef.valueOf[T]` operator has been @@ -519,7 +518,7 @@ applications which work with large datasets. valueOf[23] // result is 23: 23 ``` -+ Pattern matching against literal types and `isInstanceOf`/`asInstanceOf` tests/conversions are ++ Pattern matching against literal types and `isInstanceOf` tests are implemented via equality/identity tests of the corresponding values. Pattern matching against typed patterns (see [8.1.2 Typed @@ -527,9 +526,9 @@ applications which work with large datasets. where the `TypePat` is a literal type is translated as a match against the subsuming non-singleton type followed by an equality test with the value corresponding to the literal type. - Where applied to literal types `isInstanceOf` and `asInstanceOf` are translated to a test against + Where applied to literal types `isInstanceOf` is translated to a test against the subsuming non-singleton type and an equality test with the value corresponding to the literal - type. In the case of `asInstanceOf` a `ClassCastException` is thrown if the test fails. + type. Examples, ``` @@ -538,10 +537,13 @@ applications which work with large datasets. case _ => false } // result is true (1: Any).isInstanceOf[1] // result is true - (1: Any).asInstanceOf[1] // result is 1: 1 - (1: Any).asInstanceOf[2] // ClassCastException ``` + Importantly, that doesn't include `asInstanceOf` as that is a user assertion to the compiler, with + the compiler inserting in the generated code just enough code for the underlying runtime to not + give a `ValidationError`. The compiler should not, for instance, generate code such that an + expression like `(1: Any).asInstanceOf[2]` would throw a `ClassCastException`. + + Default initialization for vars with literal types is forbidden. The default initializer for a var is already mandated to be it's natural zero element (`0`, From 4643f1228a86fb6c347d746267989a73cc89b695 Mon Sep 17 00:00:00 2001 From: Dale Wijnand <344610+dwijnand@users.noreply.github.com> Date: Tue, 9 Jul 2019 14:41:22 +0100 Subject: [PATCH 0567/3075] Point the hacker guide to 2.13 --- contribute/hacker-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 78af87bbcd..b9e657adfb 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -10,7 +10,7 @@ This guide is intended to help you get from an idea of fixing a bug or implement This guide covers the entire process, from the conception of your idea or bugfix to the point where it is merged into Scala. Throughout, we will use a running example of an idea or bugfix one might wish to contribute. -Other good starting points for first-time contributors include the [Scala README](https://github.com/scala/scala#get-in-touch) and [contributor's guidelines](https://github.com/scala/scala/blob/2.12.x/CONTRIBUTING.md). +Other good starting points for first-time contributors include the [Scala README](https://github.com/scala/scala#get-in-touch) and [contributor's guidelines](https://github.com/scala/scala/blob/2.13.x/CONTRIBUTING.md). ## The Running Example From 7bc642cd5d844621e9bb08f9c0e8529960417c1b Mon Sep 17 00:00:00 2001 From: Srishti Jain Date: Thu, 11 Jul 2019 14:42:31 +0530 Subject: [PATCH 0568/3075] Update overview.md `TypeTags` -> `TypeTag`s --- _overviews/reflection/overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/reflection/overview.md b/_overviews/reflection/overview.md index 22b267acfa..037207df3e 100644 --- a/_overviews/reflection/overview.md +++ b/_overviews/reflection/overview.md @@ -69,7 +69,7 @@ means that if you were to inspect the runtime type of some instance, that you might not have access to all type information that the Scala compiler has available at compile time. -`TypeTags` can be thought of as objects which carry along all type information +`TypeTag`s can be thought of as objects which carry along all type information available at compile time, to runtime. Though, it's important to note that `TypeTag`s are always generated by the compiler. This generation is triggered whenever an implicit parameter or context bound requiring a `TypeTag` is used. From 2a2b92b1b6212f39b71a566532c2d605c4da3c68 Mon Sep 17 00:00:00 2001 From: Lucas Cardoso Date: Thu, 11 Jul 2019 10:18:34 -0300 Subject: [PATCH 0569/3075] Add Portuguese translation for Tuples --- _pt-br/tour/tuples.md | 73 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/_pt-br/tour/tuples.md b/_pt-br/tour/tuples.md index 8b81442317..15462f152e 100644 --- a/_pt-br/tour/tuples.md +++ b/_pt-br/tour/tuples.md @@ -1,15 +1,78 @@ --- layout: tour -title: Tuples +title: Tuplas -discourse: true +discourse: false partof: scala-tour -num: + +num: 6 next-page: mixin-class-composition previous-page: traits language: pt-br --- -(this section of the tour has not been translated yet. pull request -with translation welcome!) \ No newline at end of file +Em Scala, uma tupla é um valor que contém um número fixo de elementos, cada um com tipos distintos e as tuplas são imutaveis. + +Tuplas são sobretudo úteis para retornar múltiplos valores de um método. + +Uma Tupla com dois lementos pode ser criada dessa forma: + +```tut +val ingrediente = ("Açucar" , 25) +``` + +Isto cria uma tupla contendo dois elementos um `String` e o outro `Int`. + +O tipo inferido de `ingrediente` é `(String, Int)`, que é uma forma abreviada para `Tuple2[String, Int]` . + +Para representar tuplas, Scala usa uma serie de classes: `Tuple2`, `Tuple3`, etc., até `Tuple22` . Cada classe tem + +## Acessando os Elementos + +Uma maneira de acessar os elementos da tupla é pela sua respectiva posição. Os elementos individuais são nomeados _1 , _2 , e assim por diante. + +```tut +println(ingrediente._1) // Açucar +println(ingrediente._2) // 25 +``` + +## Correspondência de padrões em tuplas + +Uma tupla pode tambem ser desmembrada usando correspondência de padrões: + +```tut +val (nome, quantidade) = ingrediente +println(nome) // Açucar +println(quantidade) // 25 +``` + +Aqui `nome` é um tipo inferido `String` e `quantidade` é um tipo inferido `Int` . + +Outro exemplo de correspondência de padrões em uma tupla: + +```tut +val planetas = + List(("Mercurio", 57.9), ("Vénus", 108.2), ("Terra", 149.6), + ("Marte", 227.9), ("Júpiter", 778.3)) +planetas.foreach{ + case ("Terra", distancia) => + println(s"Nosso planeta está a $distancia milhões de kilometros do sol") + case _ => +} +``` + +ou, um exemplo com `for` : + +```tut +val numPars = List((2, 5), (3, -7), (20, 56)) +for ((a, b) <- numPars) { + println(a * b) +} +``` + +## Tuplas e classes case + +Desenvolvedores às vezes acham dificil escolher entre tuplas e classes case. Classes case tem elementos nomeados, e esses podem melhorar a leitura de alguns tipos de códigos. No planeta exemplo abaixo, nós poderiamos definir uma `case class Planeta(nome: String, distancia: Double)` ao invés de usar tuplas. + + From 95d2b37d36359933fdf2bcef31cb43188cee0eb1 Mon Sep 17 00:00:00 2001 From: TAKAHASHI Shuuji Date: Fri, 12 Jul 2019 04:09:02 +0900 Subject: [PATCH 0570/3075] Let match print messages to output comments --- _ja/tour/basics.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_ja/tour/basics.md b/_ja/tour/basics.md index 8eb67a0ddb..cab1c3d171 100644 --- a/_ja/tour/basics.md +++ b/_ja/tour/basics.md @@ -222,15 +222,15 @@ val yetAnotherPoint = Point(2, 2) ```tut if (point == anotherPoint) { - println(point + " and " + anotherPoint + " are the same.") + println(point + " と " + anotherPoint + " は同じです。") } else { - println(point + " and " + anotherPoint + " are different.") + println(point + " と " + anotherPoint + " は異なります。") } // Point(1,2) と Point(1,2) は同じです。 if (point == yetAnotherPoint) { - println(point + " and " + yetAnotherPoint + " are the same.") + println(point + " と " + yetAnotherPoint + " は同じです。") } else { - println(point + " and " + yetAnotherPoint + " are different.") + println(point + " と " + yetAnotherPoint + " は異なります。") } // Point(1,2) と Point(2,2) は異なります。 ``` From 61bad7b8fea308f60be8be96f1570bcc52a6e3b7 Mon Sep 17 00:00:00 2001 From: TAKAHASHI Shuuji Date: Fri, 12 Jul 2019 04:31:48 +0900 Subject: [PATCH 0571/3075] =?UTF-8?q?Replace=20comma=20with=20reading=20po?= =?UTF-8?q?int=20(,=20=E2=86=92=20=E3=80=81)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _ja/tour/unified-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_ja/tour/unified-types.md b/_ja/tour/unified-types.md index c694663c59..ab65765d37 100644 --- a/_ja/tour/unified-types.md +++ b/_ja/tour/unified-types.md @@ -25,7 +25,7 @@ Anyは `equals`、` hashCode`、そして `toString`のようないくつかの そして`AnyVal`と`AnyRef` という2つの直系のサブクラスを持ちます。 `AnyVal` は値型に相当します。 -事前に定義された9つの値型が存在し、それら`Double`, `Float`, `Long`, `Int`, `Short`, `Byte`, `Char`, `Unit`,`Boolean`は +事前に定義された9つの値型が存在し、それら`Double`、`Float`、`Long`、`Int`、`Short`、`Byte`、`Char`、`Unit`、`Boolean`は null非許容です。 `Unit`は意味のある情報をもたない値型です。`Unit`型のインスタンスはただ1つだけあり、`()`というリテラルで宣言することができます。 全ての関数は必ず何かを返さなければなりません。そのため`Unit`は戻り値の型として時々役立ちます。 From 20b9bbc651c5c939b2e4bd199c700166bc7008ee Mon Sep 17 00:00:00 2001 From: TAKAHASHI Shuuji Date: Fri, 12 Jul 2019 04:55:40 +0900 Subject: [PATCH 0572/3075] Remove a unneeded space --- _ja/tour/unified-types.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_ja/tour/unified-types.md b/_ja/tour/unified-types.md index ab65765d37..0317f06fe4 100644 --- a/_ja/tour/unified-types.md +++ b/_ja/tour/unified-types.md @@ -21,7 +21,7 @@ Scalaでは数値や関数を含め、全ての値は型を持ちます。 ## Scalaの型階層 ## [`Any`](http://www.scala-lang.org/api/2.12.1/scala/Any.html) は全ての型のスーパータイプであり、トップ型とも呼ばれます。 -Anyは `equals`、` hashCode`、そして `toString`のようないくつかの普遍的なメソッドを定義しています。 +Anyは `equals`、`hashCode`、そして `toString`のようないくつかの普遍的なメソッドを定義しています。 そして`AnyVal`と`AnyRef` という2つの直系のサブクラスを持ちます。 `AnyVal` は値型に相当します。 From a5bdc323a457701a65852bc04e745870f7352b7d Mon Sep 17 00:00:00 2001 From: "Aaron S. Hawley" Date: Thu, 11 Jul 2019 17:05:23 -0400 Subject: [PATCH 0573/3075] Move Scaladoc interface in menu as second --- _overviews/scaladoc/for-library-authors.md | 2 +- _overviews/scaladoc/interface.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_overviews/scaladoc/for-library-authors.md b/_overviews/scaladoc/for-library-authors.md index 9d3fc9e9a3..eb747c025c 100644 --- a/_overviews/scaladoc/for-library-authors.md +++ b/_overviews/scaladoc/for-library-authors.md @@ -7,7 +7,7 @@ discourse: true partof: scaladoc overview-name: Scaladoc -num: 2 +num: 3 permalink: /overviews/scaladoc/:title.html --- diff --git a/_overviews/scaladoc/interface.md b/_overviews/scaladoc/interface.md index f64417c2be..75a95d4f10 100644 --- a/_overviews/scaladoc/interface.md +++ b/_overviews/scaladoc/interface.md @@ -7,7 +7,7 @@ discourse: true partof: scaladoc overview-name: Scaladoc -num: 3 +num: 2 permalink: /overviews/scaladoc/:title.html --- From d7c05b665528136b17e0e86eafbfd27050c958e5 Mon Sep 17 00:00:00 2001 From: exoego Date: Fri, 5 Jul 2019 20:03:05 +0900 Subject: [PATCH 0574/3075] Do not remove language code from page.url --- _includes/sidebar-toc-multipage-overview.html | 2 +- _includes/sidebar-toc-singlepage-overview.html | 2 +- _layouts/cheatsheet.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_includes/sidebar-toc-multipage-overview.html b/_includes/sidebar-toc-multipage-overview.html index f454abc5e6..8d2e419efc 100644 --- a/_includes/sidebar-toc-multipage-overview.html +++ b/_includes/sidebar-toc-multipage-overview.html @@ -27,7 +27,7 @@
Contents
+
+ {% if page.previous-page %} + previous + {% else %} +
+ {% endif %} + {% if page.next-page %} + next + {% endif %} +
+ {% include contributors-list.html %}
diff --git a/_overviews/collections-2.13/arrays.md b/_overviews/collections-2.13/arrays.md index 461d1edc1d..65c2a82d2f 100644 --- a/_overviews/collections-2.13/arrays.md +++ b/_overviews/collections-2.13/arrays.md @@ -8,6 +8,8 @@ partof: collections-213 overview-name: Collections num: 10 +previous-page: concrete-mutable-collection-classes +next-page: strings permalink: /overviews/collections-2.13/:title.html --- diff --git a/_overviews/collections-2.13/concrete-immutable-collection-classes.md b/_overviews/collections-2.13/concrete-immutable-collection-classes.md index f2327fe8d8..a93e1911cf 100644 --- a/_overviews/collections-2.13/concrete-immutable-collection-classes.md +++ b/_overviews/collections-2.13/concrete-immutable-collection-classes.md @@ -8,6 +8,8 @@ partof: collections-213 overview-name: Collections num: 8 +previous-page: maps +next-page: concrete-mutable-collection-classes permalink: /overviews/collections-2.13/:title.html --- diff --git a/_overviews/collections-2.13/concrete-mutable-collection-classes.md b/_overviews/collections-2.13/concrete-mutable-collection-classes.md index 9ddd1242ef..21b373078b 100644 --- a/_overviews/collections-2.13/concrete-mutable-collection-classes.md +++ b/_overviews/collections-2.13/concrete-mutable-collection-classes.md @@ -8,6 +8,8 @@ partof: collections-213 overview-name: Collections num: 9 +previous-page: concrete-immutable-collection-classes +next-page: arrays permalink: /overviews/collections-2.13/:title.html --- diff --git a/_overviews/collections-2.13/conversions-between-java-and-scala-collections.md b/_overviews/collections-2.13/conversions-between-java-and-scala-collections.md index a1bf75ff12..b23967df24 100644 --- a/_overviews/collections-2.13/conversions-between-java-and-scala-collections.md +++ b/_overviews/collections-2.13/conversions-between-java-and-scala-collections.md @@ -8,6 +8,7 @@ partof: collections-213 overview-name: Collections num: 17 +previous-page: creating-collections-from-scratch permalink: /overviews/collections-2.13/:title.html --- diff --git a/_overviews/collections-2.13/creating-collections-from-scratch.md b/_overviews/collections-2.13/creating-collections-from-scratch.md index 7f5a0b4ca2..7305a4b13d 100644 --- a/_overviews/collections-2.13/creating-collections-from-scratch.md +++ b/_overviews/collections-2.13/creating-collections-from-scratch.md @@ -8,6 +8,8 @@ partof: collections-213 overview-name: Collections num: 16 +previous-page: iterators +next-page: conversions-between-java-and-scala-collections permalink: /overviews/collections-2.13/:title.html --- diff --git a/_overviews/collections-2.13/equality.md b/_overviews/collections-2.13/equality.md index 68f5f4141c..6be2ab45a6 100644 --- a/_overviews/collections-2.13/equality.md +++ b/_overviews/collections-2.13/equality.md @@ -8,6 +8,8 @@ partof: collections-213 overview-name: Collections num: 13 +previous-page: performance-characteristics +next-page: views permalink: /overviews/collections-2.13/:title.html --- diff --git a/_overviews/collections-2.13/introduction.md b/_overviews/collections-2.13/introduction.md index 7d27aec31f..2b238045da 100644 --- a/_overviews/collections-2.13/introduction.md +++ b/_overviews/collections-2.13/introduction.md @@ -8,6 +8,7 @@ partof: collections-213 overview-name: Collections num: 1 +next-page: overview permalink: /overviews/collections-2.13/:title.html --- diff --git a/_overviews/collections-2.13/iterators.md b/_overviews/collections-2.13/iterators.md index d2736f49b6..915e3d1018 100644 --- a/_overviews/collections-2.13/iterators.md +++ b/_overviews/collections-2.13/iterators.md @@ -8,6 +8,8 @@ partof: collections-213 overview-name: Collections num: 15 +previous-page: views +next-page: creating-collections-from-scratch permalink: /overviews/collections-2.13/:title.html --- diff --git a/_overviews/collections-2.13/maps.md b/_overviews/collections-2.13/maps.md index 9d89489c6f..7097e9e38d 100644 --- a/_overviews/collections-2.13/maps.md +++ b/_overviews/collections-2.13/maps.md @@ -8,8 +8,10 @@ partof: collections-213 overview-name: Collections num: 7 +previous-page: sets +next-page: concrete-immutable-collection-classes -permalink: /overviews/collections2.13/:title.html +permalink: /overviews/collections-2.13/:title.html --- A [Map](http://www.scala-lang.org/api/current/scala/collection/Map.html) is an [Iterable](http://www.scala-lang.org/api/current/scala/collection/Iterable.html) consisting of pairs of keys and values (also named _mappings_ or _associations_). Scala's [Predef](http://www.scala-lang.org/api/current/scala/Predef$.html) object offers an implicit conversion that lets you write `key -> value` as an alternate syntax for the pair `(key, value)`. For instance `Map("x" -> 24, "y" -> 25, "z" -> 26)` means exactly the same as `Map(("x", 24), ("y", 25), ("z", 26))`, but reads better. diff --git a/_overviews/collections-2.13/overview.md b/_overviews/collections-2.13/overview.md index a96995b662..681566cd85 100644 --- a/_overviews/collections-2.13/overview.md +++ b/_overviews/collections-2.13/overview.md @@ -8,6 +8,8 @@ partof: collections-213 overview-name: Collections num: 2 +previous-page: introduction +next-page: trait-iterable permalink: /overviews/collections-2.13/:title.html --- diff --git a/_overviews/collections-2.13/performance-characteristics.md b/_overviews/collections-2.13/performance-characteristics.md index 9c46cfc8d2..e706b078a1 100644 --- a/_overviews/collections-2.13/performance-characteristics.md +++ b/_overviews/collections-2.13/performance-characteristics.md @@ -8,6 +8,8 @@ partof: collections-213 overview-name: Collections num: 12 +previous-page: strings +next-page: equality permalink: /overviews/collections-2.13/:title.html --- diff --git a/_overviews/collections-2.13/seqs.md b/_overviews/collections-2.13/seqs.md index 4cd3060b68..1ad5a91c52 100644 --- a/_overviews/collections-2.13/seqs.md +++ b/_overviews/collections-2.13/seqs.md @@ -8,6 +8,8 @@ partof: collections-213 overview-name: Collections num: 5 +previous-page: trait-iterable +next-page: sets permalink: /overviews/collections-2.13/:title.html --- diff --git a/_overviews/collections-2.13/sets.md b/_overviews/collections-2.13/sets.md index 9189d179e1..37ac00855a 100644 --- a/_overviews/collections-2.13/sets.md +++ b/_overviews/collections-2.13/sets.md @@ -8,6 +8,8 @@ partof: collections-213 overview-name: Collections num: 6 +previous-page: seqs +next-page: maps permalink: /overviews/collections-2.13/:title.html --- diff --git a/_overviews/collections-2.13/strings.md b/_overviews/collections-2.13/strings.md index 1b84877b51..f869e5dd67 100644 --- a/_overviews/collections-2.13/strings.md +++ b/_overviews/collections-2.13/strings.md @@ -8,6 +8,8 @@ partof: collections-213 overview-name: Collections num: 11 +previous-page: arrays +next-page: performance-characteristics permalink: /overviews/collections-2.13/:title.html --- diff --git a/_overviews/collections-2.13/trait-iterable.md b/_overviews/collections-2.13/trait-iterable.md index e306f39f16..aedbd5915d 100644 --- a/_overviews/collections-2.13/trait-iterable.md +++ b/_overviews/collections-2.13/trait-iterable.md @@ -8,6 +8,8 @@ partof: collections-213 overview-name: Collections num: 4 +previous-page: overview +next-page: seqs permalink: /overviews/collections-2.13/:title.html --- diff --git a/_overviews/collections-2.13/views.md b/_overviews/collections-2.13/views.md index 61ebae3cef..97401e510f 100644 --- a/_overviews/collections-2.13/views.md +++ b/_overviews/collections-2.13/views.md @@ -8,6 +8,8 @@ partof: collections-213 overview-name: Collections num: 14 +previous-page: equality +next-page: iterators permalink: /overviews/collections-2.13/:title.html --- From c56c5bdcf5e6ef1c566e52027acf0e5d82d68b63 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Thu, 18 Jul 2019 11:10:49 +0200 Subject: [PATCH 0599/3075] Add missing URL for seqs.html page --- _data/overviews.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/_data/overviews.yml b/_data/overviews.yml index c84a29131c..bd12fb5844 100644 --- a/_data/overviews.yml +++ b/_data/overviews.yml @@ -15,6 +15,7 @@ - title: Trait Iterable url: "collections-2.13/trait-iterable.html" - title: The sequence traits Seq, IndexedSeq, and LinearSeq + url: "collections-2.13/seqs.html" - title: Concrete Immutable Collection Classes url: "collections-2.13/concrete-immutable-collection-classes.html" - title: Concrete Mutable Collection Classes From 4fad8b1ed1ad2978910f435145aa04eb4703ffb8 Mon Sep 17 00:00:00 2001 From: exoego Date: Fri, 19 Jul 2019 06:32:12 +0900 Subject: [PATCH 0600/3075] Instruct --help command as manual, sice nightly/docs are removed. --- _overviews/scaladoc/generate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scaladoc/generate.md b/_overviews/scaladoc/generate.md index 4c26f39a08..31b1b84428 100644 --- a/_overviews/scaladoc/generate.md +++ b/_overviews/scaladoc/generate.md @@ -46,7 +46,7 @@ This will put the HTML in the current directory. This is probably not what you $ scaladoc -d build/ src/main/scala/App.scala -For more information on the `scaladoc` command and what other command-line options it supports, see the [scaladoc man page](https://www.scala-lang.org/files/archive/nightly/docs/manual/html/scaladoc.html). +For more information on the `scaladoc` command and what other command-line options it supports, see the `scaladoc --help`. This command is harder to operate with more complex projects containing both multiple Scala source files and library dependencies. This is why using sbt (see above) is easier and better suited for generating Scaladoc. From ef3c5b183da297ef3dc89ff0e9e2a30d50da66de Mon Sep 17 00:00:00 2001 From: exoego Date: Fri, 19 Jul 2019 07:15:36 +0900 Subject: [PATCH 0601/3075] Escape special characters in string --- _data/compiler-options.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_data/compiler-options.yml b/_data/compiler-options.yml index 429f31b0c7..dc6649d8f1 100644 --- a/_data/compiler-options.yml +++ b/_data/compiler-options.yml @@ -429,7 +429,7 @@ - option: "-Xno-uescape" schema: type: "Boolean" - description: "Disable handling of \u unicode escapes." + description: "Disable handling of \\u unicode escapes." - option: "-Xnojline" schema: type: "Boolean" @@ -812,7 +812,7 @@ type: "String" arg: "path" default: - description: "Write repl-generated classfiles to given output directory (use "" to generate a temporary dir)" + description: "Write repl-generated classfiles to given output directory (use \"\" to generate a temporary dir)" - option: "-Yrepl-sync" schema: type: "Boolean" From c3759bc905de544a1d2586492c346d75d7c784fb Mon Sep 17 00:00:00 2001 From: exoego Date: Fri, 19 Jul 2019 07:15:46 +0900 Subject: [PATCH 0602/3075] Indent choices --- _data/compiler-options.yml | 380 ++++++++++++++++++------------------- 1 file changed, 190 insertions(+), 190 deletions(-) diff --git a/_data/compiler-options.yml b/_data/compiler-options.yml index dc6649d8f1..7f97ccede2 100644 --- a/_data/compiler-options.yml +++ b/_data/compiler-options.yml @@ -79,11 +79,11 @@ arg: "level" default: "vars" choices: - - choice: "none" - - choice: "source" - - choice: "line" - - choice: "vars" - - choice: "notailcalls" + - choice: "none" + - choice: "source" + - choice: "line" + - choice: "vars" + - choice: "notailcalls" description: "Set level of generated debugging info. Choices: (none,source,line,vars,notailcalls), default: vars." - option: "-help" schema: @@ -107,20 +107,20 @@ arg: "feature" multiple: "true" choices: - - choice: "dynamics" - description: "Allow direct or indirect subclasses of scala.Dynamic" - - choice: "postfixOps" - description: "Allow postfix operator notation, such as `1 to 10 toList`" - - choice: "reflectiveCalls" - description: "Allow reflective access to members of structural types" - - choice: "implicitConversions" - description: "Allow definition of implicit functions called views" - - choice: "higherKinds" - description: "Allow higher-kinded types" - - choice: "existentials" - description: "Existential types (besides wildcard types) can be written and inferred" - - choice: "experimental.macros" - description: "Allow macro definition (besides implementation and application)" + - choice: "dynamics" + description: "Allow direct or indirect subclasses of scala.Dynamic" + - choice: "postfixOps" + description: "Allow postfix operator notation, such as `1 to 10 toList`" + - choice: "reflectiveCalls" + description: "Allow reflective access to members of structural types" + - choice: "implicitConversions" + description: "Allow definition of implicit functions called views" + - choice: "higherKinds" + description: "Allow higher-kinded types" + - choice: "existentials" + description: "Existential types (besides wildcard types) can be written and inferred" + - choice: "experimental.macros" + description: "Allow macro definition (besides implementation and application)" description: "Enable or disable language features: `_` for all, `-language:help` to list choices." - option: "-no-specialization" schema: @@ -140,36 +140,36 @@ arg: "optimization" multiple: "true" choices: - - choice: "unreachable-code" - description: "Eliminate unreachable code, exception handlers guarding no instructions, redundant metadata (debug information, line numbers)." - - choice: "simplify-jumps" - description: "Simplify branching instructions, eliminate unnecessary ones." - - choice: "compact-locals" - description: "Eliminate empty slots in the sequence of local variables." - - choice: "copy-propagation" - description: "Eliminate redundant local variables and unused values (including closures). Enables unreachable-code." - - choice: "redundant-casts" - description: "Eliminate redundant casts using a type propagation analysis." - - choice: "box-unbox" - description: "Eliminate box-unbox pairs within the same method (also tuples, xRefs, value class instances). Enables unreachable-code." - - choice: "nullness-tracking" - description: "Track nullness / non-nullness of local variables and apply optimizations." - - choice: "closure-invocations" - description: "Rewrite closure invocations to the implementation method." - - choice: "inline" - description: "Inline method invocations according to -Yopt-inline-heuristics and -opt-inline-from." - - choice: "l:none" - description: "Disable optimizations. Takes precedence: `-opt:l:none,+box-unbox` / `-opt:l:none -opt:box-unbox` don`t enable box-unbox." - - choice: "l:default" - description: "Enable default optimizations: unreachable-code." - - choice: "l:method" - description: "Enable intra-method optimizations: unreachable-code,simplify-jumps,compact-locals,copy-propagation,redundant-casts,box-unbox,nullness-tracking,closure-invocations." - - choice: "l:inline" - description: "Enable cross-method optimizations (note: inlining requires -opt-inline-from): l:method,inline." - - choice: "l:project" - description: "[deprecated, use -opt:l:inline, -opt-inline-from] Enable cross-method optimizations within the current project." - - choice: "l:classpath" - description: "[deprecated, use -opt:l:inline, -opt-inline-from] Enable cross-method optimizations across the entire classpath." + - choice: "unreachable-code" + description: "Eliminate unreachable code, exception handlers guarding no instructions, redundant metadata (debug information, line numbers)." + - choice: "simplify-jumps" + description: "Simplify branching instructions, eliminate unnecessary ones." + - choice: "compact-locals" + description: "Eliminate empty slots in the sequence of local variables." + - choice: "copy-propagation" + description: "Eliminate redundant local variables and unused values (including closures). Enables unreachable-code." + - choice: "redundant-casts" + description: "Eliminate redundant casts using a type propagation analysis." + - choice: "box-unbox" + description: "Eliminate box-unbox pairs within the same method (also tuples, xRefs, value class instances). Enables unreachable-code." + - choice: "nullness-tracking" + description: "Track nullness / non-nullness of local variables and apply optimizations." + - choice: "closure-invocations" + description: "Rewrite closure invocations to the implementation method." + - choice: "inline" + description: "Inline method invocations according to -Yopt-inline-heuristics and -opt-inline-from." + - choice: "l:none" + description: "Disable optimizations. Takes precedence: `-opt:l:none,+box-unbox` / `-opt:l:none -opt:box-unbox` don`t enable box-unbox." + - choice: "l:default" + description: "Enable default optimizations: unreachable-code." + - choice: "l:method" + description: "Enable intra-method optimizations: unreachable-code,simplify-jumps,compact-locals,copy-propagation,redundant-casts,box-unbox,nullness-tracking,closure-invocations." + - choice: "l:inline" + description: "Enable cross-method optimizations (note: inlining requires -opt-inline-from): l:method,inline." + - choice: "l:project" + description: "[deprecated, use -opt:l:inline, -opt-inline-from] Enable cross-method optimizations within the current project." + - choice: "l:classpath" + description: "[deprecated, use -opt:l:inline, -opt-inline-from] Enable cross-method optimizations across the entire classpath." description: "Enable optimizations: `_` for all, `-opt:help` to list choices." - option: "-opt-inline-from" schema: @@ -183,20 +183,20 @@ arg: "warning" multiple: "true" choices: - - choice: "none" - description: "No optimizer warnings." - - choice: "at-inline-failed-summary" - description: "One-line summary if there were @inline method calls that could not be inlined." - - choice: "at-inline-failed" - description: "A detailed warning for each @inline method call that could not be inlined." - - choice: "any-inline-failed" - description: "A detailed warning for every callsite that was chosen for inlining by the heuristics, but could not be inlined." - - choice: "no-inline-mixed" - description: "In mixed compilation, warn at callsites methods defined in java sources (the inlining decision cannot be made without bytecode)." - - choice: "no-inline-missing-bytecode" - description: "Warn if an inlining decision cannot be made because a the bytecode of a class or member cannot be found on the compilation classpath." - - choice: "no-inline-missing-attribute" - description: "Warn if an inlining decision cannot be made because a Scala classfile does not have a ScalaInlineInfo attribute." + - choice: "none" + description: "No optimizer warnings." + - choice: "at-inline-failed-summary" + description: "One-line summary if there were @inline method calls that could not be inlined." + - choice: "at-inline-failed" + description: "A detailed warning for each @inline method call that could not be inlined." + - choice: "any-inline-failed" + description: "A detailed warning for every callsite that was chosen for inlining by the heuristics, but could not be inlined." + - choice: "no-inline-mixed" + description: "In mixed compilation, warn at callsites methods defined in java sources (the inlining decision cannot be made without bytecode)." + - choice: "no-inline-missing-bytecode" + description: "Warn if an inlining decision cannot be made because a the bytecode of a class or member cannot be found on the compilation classpath." + - choice: "no-inline-missing-attribute" + description: "Warn if an inlining decision cannot be made because a Scala classfile does not have a ScalaInlineInfo attribute." description: "Enable optimizer warnings: `_` for all, `-opt-warnings:help` to list choices." - option: "-optimise" schema: @@ -226,10 +226,10 @@ arg: "target" default: "jvm-1.8" choices: - - choice: "jvm-1.5" - - choice: "jvm-1.6" - - choice: "jvm-1.7" - - choice: "jvm-1.8" + - choice: "jvm-1.5" + - choice: "jvm-1.6" + - choice: "jvm-1.7" + - choice: "jvm-1.8" description: "Target platform for object files. All JVM 1.5 - 1.7 targets are deprecated. Choices: (jvm-1.5,jvm-1.6,jvm-1.7,jvm-1.8), default: jvm-1.8." - option: "-toolcp" schema: @@ -313,42 +313,42 @@ arg: "warning" multiple: "true" choices: - - choice: "adapted-args" - description: "Warn if an argument list is modified to match the receiver." - - choice: "nullary-unit" - description: "Warn when nullary methods return Unit." - - choice: "inaccessible" - description: "Warn about inaccessible types in method signatures." - - choice: "nullary-override" - description: "Warn when non-nullary `def f()` overrides nullary `def f`." - - choice: "infer-any" - description: "Warn when a type argument is inferred to be `Any`." - - choice: "missing-interpolator" - description: "A string literal appears to be missing an interpolator id." - - choice: "doc-detached" - description: "A Scaladoc comment appears to be detached from its element." - - choice: "private-shadow" - description: "A private field (or class parameter) shadows a superclass field." - - choice: "type-parameter-shadow" - description: "A local type parameter shadows a type already in scope." - - choice: "poly-implicit-overload" - description: "Parameterized overloaded implicit methods are not visible as view bounds." - - choice: "option-implicit" - description: "Option.apply used implicit view." - - choice: "delayedinit-select" - description: "Selecting member of DelayedInit." - - choice: "by-name-right-associative" - description: "By-name parameter of right associative operator." - - choice: "package-object-classes" - description: "Class or object defined in package object." - - choice: "unsound-match" - description: "Pattern match may not be typesafe." - - choice: "stars-align" - description: "Pattern sequence wildcard must align with sequence component." - - choice: "constant" - description: "Evaluation of a constant arithmetic expression results in an error." - - choice: "unused" - description: "Enable -Ywarn-unused:imports,privates,locals,implicits." + - choice: "adapted-args" + description: "Warn if an argument list is modified to match the receiver." + - choice: "nullary-unit" + description: "Warn when nullary methods return Unit." + - choice: "inaccessible" + description: "Warn about inaccessible types in method signatures." + - choice: "nullary-override" + description: "Warn when non-nullary `def f()` overrides nullary `def f`." + - choice: "infer-any" + description: "Warn when a type argument is inferred to be `Any`." + - choice: "missing-interpolator" + description: "A string literal appears to be missing an interpolator id." + - choice: "doc-detached" + description: "A Scaladoc comment appears to be detached from its element." + - choice: "private-shadow" + description: "A private field (or class parameter) shadows a superclass field." + - choice: "type-parameter-shadow" + description: "A local type parameter shadows a type already in scope." + - choice: "poly-implicit-overload" + description: "Parameterized overloaded implicit methods are not visible as view bounds." + - choice: "option-implicit" + description: "Option.apply used implicit view." + - choice: "delayedinit-select" + description: "Selecting member of DelayedInit." + - choice: "by-name-right-associative" + description: "By-name parameter of right associative operator." + - choice: "package-object-classes" + description: "Class or object defined in package object." + - choice: "unsound-match" + description: "Pattern match may not be typesafe." + - choice: "stars-align" + description: "Pattern sequence wildcard must align with sequence component." + - choice: "constant" + description: "Evaluation of a constant arithmetic expression results in an error." + - choice: "unused" + description: "Enable -Ywarn-unused:imports,privates,locals,implicits." description: "Enable or disable specific warnings: `_` for all, `-Xlint:help` to list choices." - option: "-Xlog-free-terms" schema: @@ -411,12 +411,12 @@ arg: "mode" default: "true" choices: - - choice: "true" - description: "Always generate mixin forwarders." - - choice: "junit" - description: "Generate mixin forwarders for JUnit-annotated methods (JUnit 4 does not support default methods)." - - choice: "false" - description: "Only generate mixin forwarders required for program correctness." + - choice: "true" + description: "Always generate mixin forwarders." + - choice: "junit" + description: "Generate mixin forwarders for JUnit-annotated methods (JUnit 4 does not support default methods)." + - choice: "false" + description: "Only generate mixin forwarders required for program correctness." description: "Generate forwarder methods in classes inhering concrete methods from traits. Default: `true`, `help` to list choices." - option: "-Xno-forwarders" schema: @@ -541,8 +541,8 @@ arg: "property" multiple: "true" choices: - - choice: "coalescing" - description: "Convert PCData to Text and coalesce sibling nodes" + - choice: "coalescing" + description: "Convert PCData to Text and coalesce sibling nodes" description: "Configure XML parsing.: `_` for all, `-Xxml:help` to list choices." - category: "Verbose Settings" description: @@ -579,10 +579,10 @@ arg: "policy" default: "none" choices: - - choice: "none" - description: "Don't cache class loader" - - choice: "last-modified" - description: "Cache class loader, using file last-modified time to invalidate" + - choice: "none" + description: "Don't cache class loader" + - choice: "last-modified" + description: "Cache class loader, using file last-modified time to invalidate" description: "Policy for caching class loaders for macros that are dynamically loaded. Default: `none`, `help` to list choices." - option: "-Ycache-plugin-class-loader" schema: @@ -590,10 +590,10 @@ arg: "policy" default: "none" choices: - - choice: "none" - description: "Don't cache class loader" - - choice: "last-modified" - description: "Cache class loader, using file last-modified time to invalidate" + - choice: "none" + description: "Don't cache class loader" + - choice: "last-modified" + description: "Cache class loader, using file last-modified time to invalidate" description: "Policy for caching class loaders for compiler plugins that are dynamically loaded. Default: `none`, `help` to list choices." - option: "-Ycheck" schema: @@ -614,8 +614,8 @@ arg: "strategy" default: "method" choices: - - choice: "inline" - - choice: "method" + - choice: "inline" + - choice: "method" description: "Strategy used for translating lambdas into JVM code. Choices: (inline,method), default: method." - option: "-YdisableFlatCpCaching" schema: @@ -683,9 +683,9 @@ arg: "policy" default: "normal" choices: - - choice: "normal" - - choice: "none" - - choice: "discard" + - choice: "normal" + - choice: "none" + - choice: "discard" description: "Control expansion of macros, useful for scaladoc and presentation compiler. Choices: (normal,none,discard), default: normal." - option: "-Ymacro-no-expand" schema: @@ -717,9 +717,9 @@ arg: "strategy" default: "default" choices: - - choice: "at-inline-annotated" - - choice: "everything" - - choice: "default" + - choice: "at-inline-annotated" + - choice: "everything" + - choice: "default" description: "Set the heuristics for inlining decisions. Choices: (at-inline-annotated,everything,default), default: default." - option: "-Yopt-log-inline" schema: @@ -823,9 +823,9 @@ arg: "strategy" default: "error" choices: - - choice: "package" - - choice: "object" - - choice: "error" + - choice: "package" + - choice: "object" + - choice: "error" description: "Resolve term conflicts. Choices: (package,object,error), default: error." - option: "-Yshow" schema: @@ -923,14 +923,14 @@ arg: "mode" default: "before" choices: - - choice: "none" - description: "Do not inspect expansions or their original trees when generating unused symbol warnings." - - choice: "before" - description: "Only inspect unexpanded user-written code for unused symbols." - - choice: "after" - description: "Only inspect expanded trees when generating unused symbol warnings." - - choice: "both" - description: "Inspect both user-written code and expanded trees when generating unused symbol warnings." + - choice: "none" + description: "Do not inspect expansions or their original trees when generating unused symbol warnings." + - choice: "before" + description: "Only inspect unexpanded user-written code for unused symbols." + - choice: "after" + description: "Only inspect expanded trees when generating unused symbol warnings." + - choice: "both" + description: "Inspect both user-written code and expanded trees when generating unused symbol warnings." description: "Enable lint warnings on macro expansions. Default: `before`, `help` to list choices." - option: "-Ywarn-nullary-override" schema: @@ -954,22 +954,22 @@ arg: "warning" multiple: "true" choices: - - choice: "imports" - description: "Warn if an import selector is not referenced." - - choice: "patvars" - description: "Warn if a variable bound in a pattern is unused." - - choice: "privates" - description: "Warn if a private member is unused." - - choice: "locals" - description: "Warn if a local definition is unused." - - choice: "explicits" - description: "Warn if an explicit parameter is unused." - - choice: "implicits" - description: "Warn if an implicit parameter is unused." - - choice: "params" - description: "Enable -Ywarn-unused:explicits,implicits." - - choice: "linted" - description: "-Xlint:unused." + - choice: "imports" + description: "Warn if an import selector is not referenced." + - choice: "patvars" + description: "Warn if a variable bound in a pattern is unused." + - choice: "privates" + description: "Warn if a private member is unused." + - choice: "locals" + description: "Warn if a local definition is unused." + - choice: "explicits" + description: "Warn if an explicit parameter is unused." + - choice: "implicits" + description: "Warn if an implicit parameter is unused." + - choice: "params" + description: "Enable -Ywarn-unused:explicits,implicits." + - choice: "linted" + description: "-Xlint:unused." description: "Enable or disable specific `unused` warnings: `_` for all, `-Ywarn-unused:help` to list choices." - option: "-Ywarn-unused-import" schema: @@ -988,42 +988,42 @@ arg: "warning" multiple: "true" choices: - - choice: "adapted-args" - description: "Warn if an argument list is modified to match the receiver." - - choice: "nullary-unit" - description: "Warn when nullary methods return Unit." - - choice: "inaccessible" - description: "Warn about inaccessible types in method signatures." - - choice: "nullary-override" - description: "Warn when non-nullary `def f()` overrides nullary `def f`." - - choice: "infer-any" - description: "Warn when a type argument is inferred to be `Any`." - - choice: "missing-interpolator" - description: "A string literal appears to be missing an interpolator id." - - choice: "doc-detached" - description: "A Scaladoc comment appears to be detached from its element." - - choice: "private-shadow" - description: "A private field (or class parameter) shadows a superclass field." - - choice: "type-parameter-shadow" - description: "A local type parameter shadows a type already in scope." - - choice: "poly-implicit-overload" - description: "Parameterized overloaded implicit methods are not visible as view bounds." - - choice: "option-implicit" - description: "Option.apply used implicit view." - - choice: "delayedinit-select" - description: "Selecting member of DelayedInit." - - choice: "by-name-right-associative" - description: "By-name parameter of right associative operator." - - choice: "package-object-classes" - description: "Class or object defined in package object." - - choice: "unsound-match" - description: "Pattern match may not be typesafe." - - choice: "stars-align" - description: "Pattern sequence wildcard must align with sequence component." - - choice: "constant" - description: "Evaluation of a constant arithmetic expression results in an error." - - choice: "unused" - description: "Enable -Ywarn-unused:imports,privates,locals,implicits." + - choice: "adapted-args" + description: "Warn if an argument list is modified to match the receiver." + - choice: "nullary-unit" + description: "Warn when nullary methods return Unit." + - choice: "inaccessible" + description: "Warn about inaccessible types in method signatures." + - choice: "nullary-override" + description: "Warn when non-nullary `def f()` overrides nullary `def f`." + - choice: "infer-any" + description: "Warn when a type argument is inferred to be `Any`." + - choice: "missing-interpolator" + description: "A string literal appears to be missing an interpolator id." + - choice: "doc-detached" + description: "A Scaladoc comment appears to be detached from its element." + - choice: "private-shadow" + description: "A private field (or class parameter) shadows a superclass field." + - choice: "type-parameter-shadow" + description: "A local type parameter shadows a type already in scope." + - choice: "poly-implicit-overload" + description: "Parameterized overloaded implicit methods are not visible as view bounds." + - choice: "option-implicit" + description: "Option.apply used implicit view." + - choice: "delayedinit-select" + description: "Selecting member of DelayedInit." + - choice: "by-name-right-associative" + description: "By-name parameter of right associative operator." + - choice: "package-object-classes" + description: "Class or object defined in package object." + - choice: "unsound-match" + description: "Pattern match may not be typesafe." + - choice: "stars-align" + description: "Pattern sequence wildcard must align with sequence component." + - choice: "constant" + description: "Evaluation of a constant arithmetic expression results in an error." + - choice: "unused" + description: "Enable -Ywarn-unused:imports,privates,locals,implicits." description: "Enable or disable specific warnings: `_` for all, `-Xlint:help` to list choices." - category: "IDE-specific Settings" description: From 104599e56657ee833957049f8298e7ebe005f658 Mon Sep 17 00:00:00 2001 From: exoego Date: Mon, 15 Jul 2019 19:36:11 +0900 Subject: [PATCH 0603/3075] Add language dropdown to masthead-documentation layout --- _includes/masthead-documentation.html | 28 +++++++++++++++++++++++++++ _sass/components/dropdown.scss | 11 +++++++++++ 2 files changed, 39 insertions(+) diff --git a/_includes/masthead-documentation.html b/_includes/masthead-documentation.html index a15b70e81e..0411d88942 100644 --- a/_includes/masthead-documentation.html +++ b/_includes/masthead-documentation.html @@ -1,6 +1,34 @@
+ +
+
+ Language + +
+
+ + +
{% for section in page.sections %}
diff --git a/_sass/components/dropdown.scss b/_sass/components/dropdown.scss index 30f41cb713..6cf33e73ca 100644 --- a/_sass/components/dropdown.scss +++ b/_sass/components/dropdown.scss @@ -18,6 +18,11 @@ // } float: right; + .table-of-content & { + margin-top: 0; + margin-right: 0; + } + .wrapper-dropdown { padding: 8px 18px 8px 40px; appearance: none; @@ -25,6 +30,12 @@ border-radius: $border-radius-base; box-sizing: border-box; + .table-of-content & { + border: 1px solid rgba(128, 128, 128, 0.5); + } + .table-of-content &:focus { + } + &:focus { outline: none; background: rgba(#fff, 0.9); From 2c282bb67f99d501c3a9bf3398d57357577705b4 Mon Sep 17 00:00:00 2001 From: exoego Date: Tue, 16 Jul 2019 13:34:47 +0900 Subject: [PATCH 0604/3075] Add Japanese translations of root page (index.md) --- _ja/index.md | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ index.md | 7 +++--- 2 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 _ja/index.md diff --git a/_ja/index.md b/_ja/index.md new file mode 100644 index 0000000000..12a737d4c1 --- /dev/null +++ b/_ja/index.md @@ -0,0 +1,70 @@ +--- +layout: inner-page-documentation +title: ドキュメント +language: ja +partof: documentation +discourse: true + +# Content masthead links +sections: + + - title: "最初のステップ" + links: + - title: "入門" + description: "あなたのコンピューターに Scala をインストールして、Scala コードを書きはじめよう!(英語のみ)" + icon: "fa fa-rocket" + link: /getting-started.html + - title: "Scala ツアー" + description: "コア言語機能をひと口大で紹介" + icon: "fa fa-flag" + link: /ja/tour/tour-of-scala.html + - title: "Java プログラマーのための Scala" + description: "Java 経験者向けのすばやい紹介" + icon: "fa fa-coffee" + link: /ja/tutorials/scala-for-java-programmers.html + more-resources: + - title: オンラインリソース(英語のみ) + url: /learn.html + - title: 書籍(英語のみ) + url: /books.html + + - title: "リピーター向け" + links: + - title: "API" + description: "Scala の全バージョンの API ドキュメント(英語のみ)" + icon: "fa fa-file-text" + link: /api/all.html + - title: "Overviews" + description: "Scala の多くの機能を網羅する詳細ドキュメント" + icon: "fa fa-database" + # TODO: 日本語訳はあるがリニューアル前のもの。要修正 + link: /ja/overviews/index.html + - title: "スタイルガイド" + description: "Scala らしいコードを書くための詳細なガイド(英語のみ)" + icon: "fa fa-bookmark" + link: /style/index.html + - title: "チートシート" + description: "Scala 構文の基礎を網羅する便利なチートシート" + icon: "fa fa-list" + link: /ja/cheatsheets/index.html + - title: "Scala よくある質問" + description: "Scala 言語機能についてよく聞かれる質問&回答集(英語のみ)" + icon: "fa fa-question-circle" + link: /tutorials/FAQ/index.html + - title: "言語仕様" + description: "Scala の形式的言語仕様(英語のみ)" + icon: "fa fa-book" + link: http://scala-lang.org/files/archive/spec/2.12/ + + - title: "Scala の進化" + links: + - title: "SIP" + description: "Scala Improvement Process(Scala 改善プロセス)。言語とコンパイラの進化(英語のみ)" + icon: "fa fa-cogs" + link: sips/index.html + - title: "SPP" + description: "Scala Platform Process(Scala プラットフォームプロセス)。コミュニティ主導型のライブラリの進化(英語のみ)" + icon: "fa fa-users" + link: https://platform.scala-lang.org + +--- diff --git a/index.md b/index.md index 23ed9edcd5..7a98cad905 100644 --- a/index.md +++ b/index.md @@ -1,9 +1,10 @@ --- layout: inner-page-documentation title: Documentation -#redirect_from: -# - /what-is-scala/ -#includeTOC: true +languages: [ja] +namespace: root +partof: documentation +discourse: true # Content masthead links sections: From b0f8ffb199aa437746570840c125d6136913d4ce Mon Sep 17 00:00:00 2001 From: exoego Date: Tue, 16 Jul 2019 15:43:11 +0900 Subject: [PATCH 0605/3075] Fix missing directory separator. --- _ja/index.md | 2 +- index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/_ja/index.md b/_ja/index.md index 12a737d4c1..4f22939227 100644 --- a/_ja/index.md +++ b/_ja/index.md @@ -61,7 +61,7 @@ sections: - title: "SIP" description: "Scala Improvement Process(Scala 改善プロセス)。言語とコンパイラの進化(英語のみ)" icon: "fa fa-cogs" - link: sips/index.html + link: /sips/index.html - title: "SPP" description: "Scala Platform Process(Scala プラットフォームプロセス)。コミュニティ主導型のライブラリの進化(英語のみ)" icon: "fa fa-users" diff --git a/index.md b/index.md index 7a98cad905..fb6d93db53 100644 --- a/index.md +++ b/index.md @@ -61,7 +61,7 @@ sections: - title: "SIPs" description: "The Scala Improvement Process. Language & compiler evolution." icon: "fa fa-cogs" - link: sips/index.html + link: /sips/index.html - title: "SPP" description: "The Scala Platform Process. Community-driven library evolution." icon: "fa fa-users" From a4eddf115b7e1560c0af3ca27dfdb053812dd112 Mon Sep 17 00:00:00 2001 From: Valentin Willscher Date: Fri, 19 Jul 2019 17:59:36 +0900 Subject: [PATCH 0606/3075] Naming convention exception generating/deriving formats --- _style/naming-conventions.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/_style/naming-conventions.md b/_style/naming-conventions.md index f97f3328fe..c357c6e65f 100644 --- a/_style/naming-conventions.md +++ b/_style/naming-conventions.md @@ -40,6 +40,12 @@ Classes should be named in upper camel case: This mimics the Java naming convention for classes. +Sometimes traits and classes as well as their members are used to describe +formats, documentation or protocols and generate/derive them. +In these cases it is desirable to be close to a 1:1 relation to the output format +and the naming conventions don't apply. In this case, they should only be used +for that specific purpose and not throughout the rest of the code. + ## Objects Object names are like class names (upper camel case). From e6f122e9d42f065101d4166b3b59745240737ddc Mon Sep 17 00:00:00 2001 From: Daniel Capo Sobral Date: Fri, 19 Jul 2019 12:38:12 -0600 Subject: [PATCH 0607/3075] Update for Scala 2.13 --- _overviews/macros/annotations.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_overviews/macros/annotations.md b/_overviews/macros/annotations.md index d7b70d9258..dfe7a57abb 100644 --- a/_overviews/macros/annotations.md +++ b/_overviews/macros/annotations.md @@ -16,11 +16,11 @@ permalink: /overviews/macros/:title.html **Eugene Burmako** -Macro annotations are only available with the macro paradise plugin (in Scala 2.10.x, 2.11.x and 2.12.x alike). -Their inclusion in official Scala might happen in Scala 2.13, but there is no certainty about it yet. -Follow the instructions at the ["Macro Paradise"](paradise.html) page to download and use our compiler plugin. +Macro annotations are available in Scala 2.13, but only with the macro paradise plugin from Scala 2.10.x to Scala 2.12.x. +Follow the instructions at the ["Macro Paradise"](paradise.html) page to download and use our compiler plugin if using +those older Scala versions. -Note that macro paradise is needed both to compile and to expand macro annotations, +Note that the macro paradise plugin is needed both to compile and to expand macro annotations, which means that your users will have to also add macro paradise to their builds in order to use your macro annotations. However, after macro annotations expand, the resulting code will no longer have any references to macro paradise and won't require its presence at compile-time or at runtime. From 29fa1544602a7462cfa535db964da8da2f13df15 Mon Sep 17 00:00:00 2001 From: Daniel Capo Sobral Date: Fri, 19 Jul 2019 12:40:40 -0600 Subject: [PATCH 0608/3075] Mention flag for 2.13 --- _overviews/macros/annotations.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_overviews/macros/annotations.md b/_overviews/macros/annotations.md index dfe7a57abb..154f341022 100644 --- a/_overviews/macros/annotations.md +++ b/_overviews/macros/annotations.md @@ -16,7 +16,8 @@ permalink: /overviews/macros/:title.html **Eugene Burmako** -Macro annotations are available in Scala 2.13, but only with the macro paradise plugin from Scala 2.10.x to Scala 2.12.x. +Macro annotations are available in Scala 2.13 with the `-Ymacro-annotations` flag, but only with the macro paradise +plugin from Scala 2.10.x to Scala 2.12.x. Follow the instructions at the ["Macro Paradise"](paradise.html) page to download and use our compiler plugin if using those older Scala versions. From f8699afe3297a6a9663405d937415c69114cab2c Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Fri, 14 Jun 2019 11:38:15 -0700 Subject: [PATCH 0609/3075] First update to 2.13 Still needs addition of previous material. --- _data/compiler-options.yml | 735 ++++++++++++++++++++++--------------- 1 file changed, 439 insertions(+), 296 deletions(-) diff --git a/_data/compiler-options.yml b/_data/compiler-options.yml index 7f97ccede2..fb67497392 100644 --- a/_data/compiler-options.yml +++ b/_data/compiler-options.yml @@ -15,6 +15,20 @@ arg: "plugin:opt" multiple: "true" description: "Pass an option to a plugin" + - option: "-V" + schema: + type: "Boolean" + description: "Print a synopsis of verbose options." + - option: "-W" + schema: + type: "Boolean" + description: "Print a synopsis of warning options." + - option: "-Werror" + schema: + type: "Boolean" + description: "Fail the compilation if there are any warnings." + abbreviations: + - "-Xfatal-warnings" - option: "-X" schema: type: "Boolean" @@ -29,6 +43,8 @@ arg: "path" default: description: "Override location of bootstrap class files." + abbreviations: + - "--boot-class-path" - option: "-classpath" schema: type: "Path" @@ -37,6 +53,7 @@ description: "Specify where to find user class files." abbreviations: - "-cp" + - "--class-path" - option: "-d" schema: type: "String" @@ -49,30 +66,42 @@ arg: "file" default: ".scala_dependencies" description: "Set dependency tracking file." + abbreviations: + - "--dependency-file" - option: "-deprecation" schema: type: "Boolean" description: "Emit warning and location for usages of deprecated APIs." + abbreviations: + - "--deprecation" - option: "-encoding" schema: type: "String" arg: "encoding" default: "UTF-8" description: "Specify character encoding used by source files." + abbreviations: + - "--encoding" - option: "-explaintypes" schema: type: "Boolean" description: "Explain type errors in more detail." + abbreviations: + - "--explain-types" - option: "-extdirs" schema: type: "Path" arg: "path" default: description: "Override location of installed extensions." + abbreviations: + - "--extension-directories" - option: "-feature" schema: type: "Boolean" description: "Emit warning and location for usages of features that should be imported explicitly." + abbreviations: + - "--feature" - option: "-g" schema: type: "Choice" @@ -84,23 +113,29 @@ - choice: "line" - choice: "vars" - choice: "notailcalls" - description: "Set level of generated debugging info. Choices: (none,source,line,vars,notailcalls), default: vars." + description: "Set level of generated debugging info. (none,source,line,[vars],notailcalls)" - option: "-help" schema: type: "Boolean" description: "Print a synopsis of standard options" + abbreviations: + - "--help" - option: "-javabootclasspath" schema: type: "Path" arg: "path" - default: "/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/resources.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/rt.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/sunrsasign.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jsse.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jce.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/charsets.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/jfr.jar:/usr/lib/jvm/java-8-openjdk-amd64/jre/classes" + default: "" description: "Override java boot classpath." + abbreviations: + - "--java-boot-class-path" - option: "-javaextdirs" schema: type: "Path" arg: "path" - default: "/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ext:/usr/java/packages/lib/ext" + default: description: "Override java extdirs classpath." + abbreviations: + - "--java-extension-directories" - option: "-language" schema: type: "Choice" @@ -109,31 +144,39 @@ choices: - choice: "dynamics" description: "Allow direct or indirect subclasses of scala.Dynamic" + - choice: "existentials" + description: "Existential types (besides wildcard types) can be written and inferred" + - choice: "higherKinds" + description: "Allow higher-kinded types" + - choice: "implicitConversions" + description: "Allow definition of implicit functions called views" - choice: "postfixOps" - description: "Allow postfix operator notation, such as `1 to 10 toList`" + description: "Allow postfix operator notation, such as `1 to 10 toList` (not recommended)" - choice: "reflectiveCalls" description: "Allow reflective access to members of structural types" - - choice: "implicitConversions" - description: "Allow definition of implicit functions called views" - - choice: "higherKinds" - description: "Allow higher-kinded types" - - choice: "existentials" - description: "Existential types (besides wildcard types) can be written and inferred" - choice: "experimental.macros" description: "Allow macro definition (besides implementation and application)" - description: "Enable or disable language features: `_` for all, `-language:help` to list choices." + description: "Enable or disable language features" + abbreviations: + - "--language" - option: "-no-specialization" schema: type: "Boolean" description: "Ignore @specialize annotations." + abbreviations: + - "--no-specialization" - option: "-nobootcp" schema: type: "Boolean" description: "Do not use the boot classpath for the scala jars." + abbreviations: + - "--no-boot-class-path" - option: "-nowarn" schema: type: "Boolean" description: "Generate no warnings." + abbreviations: + - "--no-warnings" - option: "-opt" schema: type: "Choice" @@ -156,6 +199,12 @@ description: "Track nullness / non-nullness of local variables and apply optimizations." - choice: "closure-invocations" description: "Rewrite closure invocations to the implementation method." + - choice: "allow-skip-core-module-init" + description: "Allow eliminating unused module loads for core modules of the standard library (e.g., Predef, ClassTag)." + - choice: "assume-modules-non-null" + description: "Assume loading a module never results in null (happens if the module is accessed in its super constructor)." + - choice: "allow-skip-class-loading" + description: "Allow optimizations that can skip or delay class loading." - choice: "inline" description: "Inline method invocations according to -Yopt-inline-heuristics and -opt-inline-from." - choice: "l:none" @@ -163,14 +212,10 @@ - choice: "l:default" description: "Enable default optimizations: unreachable-code." - choice: "l:method" - description: "Enable intra-method optimizations: unreachable-code,simplify-jumps,compact-locals,copy-propagation,redundant-casts,box-unbox,nullness-tracking,closure-invocations." + description: "Enable intra-method optimizations: unreachable-code,simplify-jumps,compact-locals,copy-propagation,redundant-casts,box-unbox,nullness-tracking,closure-invocations,allow-skip-core-module-init,assume-modules-non-null,allow-skip-class-loading." - choice: "l:inline" description: "Enable cross-method optimizations (note: inlining requires -opt-inline-from): l:method,inline." - - choice: "l:project" - description: "[deprecated, use -opt:l:inline, -opt-inline-from] Enable cross-method optimizations within the current project." - - choice: "l:classpath" - description: "[deprecated, use -opt:l:inline, -opt-inline-from] Enable cross-method optimizations across the entire classpath." - description: "Enable optimizations: `_` for all, `-opt:help` to list choices." + description: "Enable optimizations" - option: "-opt-inline-from" schema: type: "String" @@ -197,70 +242,93 @@ description: "Warn if an inlining decision cannot be made because a the bytecode of a class or member cannot be found on the compilation classpath." - choice: "no-inline-missing-attribute" description: "Warn if an inlining decision cannot be made because a Scala classfile does not have a ScalaInlineInfo attribute." - description: "Enable optimizer warnings: `_` for all, `-opt-warnings:help` to list choices." - - option: "-optimise" + description: "Enable optimizer warnings" + - option: "-optimize" schema: type: "Boolean" - description: "Compiler flag for the optimizer in Scala 2.11" + description: "Enables optimizations." abbreviations: - - "-optimize" + - "-optimise" - option: "-print" schema: type: "Boolean" description: "Print program with Scala-specific features removed." + abbreviations: + - "--print" - option: "-release" schema: type: "String" arg: "release" default: description: "Compile for a specific version of the Java platform. Supported targets: 6, 7, 8, 9" + abbreviations: + - "--release" - option: "-sourcepath" schema: type: "Path" arg: "path" default: description: "Specify location(s) of source files." + abbreviations: + - "--source-path" - option: "-target" schema: type: "Choice" arg: "target" - default: "jvm-1.8" + default: "8" choices: - - choice: "jvm-1.5" - - choice: "jvm-1.6" - - choice: "jvm-1.7" - - choice: "jvm-1.8" - description: "Target platform for object files. All JVM 1.5 - 1.7 targets are deprecated. Choices: (jvm-1.5,jvm-1.6,jvm-1.7,jvm-1.8), default: jvm-1.8." + - choice: "8" + - choice: "9" + - choice: "10" + - choice: "11" + - choice: "12" + description: "Target platform for object files. ([8],9,10,11,12)" + abbreviations: + - "--target" - option: "-toolcp" schema: type: "Path" arg: "path" default: description: "Add to the runner classpath." + abbreviations: + - "--tool-class-path" - option: "-unchecked" schema: type: "Boolean" description: "Enable additional warnings where generated code depends on assumptions." + abbreviations: + - "--unchecked" - option: "-uniqid" schema: type: "Boolean" description: "Uniquely tag all identifiers in debugging output." + abbreviations: + - "--unique-id" - option: "-usejavacp" schema: type: "Boolean" description: "Utilize the java.class.path in classpath resolution." + abbreviations: + - "--use-java-class-path" - option: "-usemanifestcp" schema: type: "Boolean" description: "Utilize the manifest in classpath resolution." + abbreviations: + - "--use-manifest-class-path" - option: "-verbose" schema: type: "Boolean" description: "Output messages about what the compiler is doing." + abbreviations: + - "--verbose" - option: "-version" schema: type: "Boolean" description: "Print product version and exit." + abbreviations: + - "--version" - option: "@" schema: type: "Boolean" @@ -288,19 +356,11 @@ - option: "-Xexperimental" schema: type: "Boolean" - description: "Enable experimental extensions." - - option: "-Xfatal-warnings" - schema: - type: "Boolean" - description: "Fail the compilation if there are any warnings." - - option: "-Xfull-lubs" - schema: - type: "Boolean" - description: "Retains pre 2.10 behavior of less aggressive truncation of least upper bounds." + description: "Former graveyard for language-forking extensions." - option: "-Xfuture" schema: type: "Boolean" - description: "Turn on future language features." + description: "Replaced by -Xsource." - option: "-Xgenerate-phase-graph" schema: type: "String" @@ -337,39 +397,29 @@ description: "Option.apply used implicit view." - choice: "delayedinit-select" description: "Selecting member of DelayedInit." - - choice: "by-name-right-associative" - description: "By-name parameter of right associative operator." - choice: "package-object-classes" description: "Class or object defined in package object." - - choice: "unsound-match" - description: "Pattern match may not be typesafe." - choice: "stars-align" description: "Pattern sequence wildcard must align with sequence component." - choice: "constant" description: "Evaluation of a constant arithmetic expression results in an error." - choice: "unused" - description: "Enable -Ywarn-unused:imports,privates,locals,implicits." - description: "Enable or disable specific warnings: `_` for all, `-Xlint:help` to list choices." - - option: "-Xlog-free-terms" - schema: - type: "Boolean" - description: "Print a message when reification creates a free term." - - option: "-Xlog-free-types" - schema: - type: "Boolean" - description: "Print a message when reification resorts to generating a free type." - - option: "-Xlog-implicit-conversions" - schema: - type: "Boolean" - description: "Print a message whenever an implicit conversion is inserted." - - option: "-Xlog-implicits" - schema: - type: "Boolean" - description: "Show more detail on why some implicits are not applicable." - - option: "-Xlog-reflective-calls" - schema: - type: "Boolean" - description: "Print a message when a reflective method call is generated" + description: "Enable -Wunused:imports,privates,locals,implicits." + - choice: "nonlocal-return" + description: "A return statement used an exception for flow control." + - choice: "implicit-not-found" + description: "Check @implicitNotFound and @implicitAmbiguous messages." + - choice: "serial" + description: "@SerialVersionUID on traits and non-serializable classes." + - choice: "valpattern" + description: "Enable pattern checks in val definitions." + - choice: "eta-zero" + description: "Warn on eta-expansion (rather than auto-application) of zero-ary method." + - choice: "eta-sam" + description: "Warn on eta-expansion to meet a Java-defined functional interface that is not explicitly annotated with @FunctionalInterface." + - choice: "deprecation" + description: "Enable linted deprecations." + description: "Enable recommended warnings" - option: "-Xmacro-settings" schema: type: "String" @@ -382,13 +432,6 @@ arg: "path" default: description: "Class for manifest's Main-Class entry (only useful with -d jar)" - - option: "-Xmax-classfile-name" - schema: - type: "Int" - default: "255" - min: "72" - max: "255" - description: "Maximum filename length for generated classes" - option: "-Xmaxerrs" schema: type: "Int" @@ -460,25 +503,8 @@ schema: type: "String" arg: "path" - default: "misc/scala-devel/plugins" + default: "" description: "Path to search for plugin archives." - - option: "-Xprint" - schema: - type: "Phases" - default: - description: "Print out program after phases" - - option: "-Xprint-args" - schema: - type: "Boolean" - description: "Print all compiler arguments and exit." - - option: "-Xprint-pos" - schema: - type: "Boolean" - description: "Print tree positions, as offsets." - - option: "-Xprint-types" - schema: - type: "Boolean" - description: "Print tree types (debugging option)." - option: "-Xprompt" schema: type: "Boolean" @@ -499,27 +525,11 @@ arg: "object" default: description: "Treat the source file as a script and wrap it in a main method." - - option: "-Xshow-class" - schema: - type: "String" - arg: "class" - default: - description: "Show internal representation of class." - - option: "-Xshow-object" - schema: - type: "String" - arg: "object" - default: - description: "Show internal representation of object." - - option: "-Xshow-phases" - schema: - type: "Boolean" - description: "Print a synopsis of compiler phases." - option: "-Xsource" schema: type: "ScalaVersion" arg: "version" - default: "2.12.0" + default: "2.13.0" description: "Treat compiler input as Scala source for the specified version, see scala/bug#8126." - option: "-Xsource-reader" schema: @@ -527,10 +537,6 @@ arg: "classname" default: description: "Specify a custom method for reading source files." - - option: "-Xstrict-inference" - schema: - type: "Boolean" - description: "Don't infer known-unsound types" - option: "-Xverify" schema: type: "Boolean" @@ -543,10 +549,237 @@ choices: - choice: "coalescing" description: "Convert PCData to Text and coalesce sibling nodes" - description: "Configure XML parsing.: `_` for all, `-Xxml:help` to list choices." + description: "Configure XML parsing." - category: "Verbose Settings" description: options: + - option: "-Vbrowse" + schema: + type: "Phases" + default: + description: "Browse the abstract syntax tree after phases" + abbreviations: + - "-Ybrowse" + - option: "-Vclasspath" + schema: + type: "Boolean" + description: "Output information about what classpath is being applied." + abbreviations: + - "-Ylog-classpath" + - option: "-Vdebug" + schema: + type: "Boolean" + description: "Increase the quantity of debugging output." + abbreviations: + - "-Ydebug" + - option: "-Vdoc" + schema: + type: "Boolean" + description: "Trace scaladoc activity." + abbreviations: + - "-Ydoc-debug" + - option: "-Vfree-terms" + schema: + type: "Boolean" + description: "Print a message when reification creates a free term." + abbreviations: + - "-Xlog-free-terms" + - option: "-Vfree-types" + schema: + type: "Boolean" + description: "Print a message when reification resorts to generating a free type." + abbreviations: + - "-Xlog-free-types" + - option: "-Vhot-statistics" + schema: + type: "Boolean" + description: "Enable `-Vstatistics` to also print hot statistics." + abbreviations: + - "-Yhot-statistics" + - option: "-Vide" + schema: + type: "Boolean" + description: "Generate, validate and output trees using the interactive compiler." + abbreviations: + - "-Yide-debug" + - option: "-Vimplicit-conversions" + schema: + type: "Boolean" + description: "Print a message whenever an implicit conversion is inserted." + abbreviations: + - "-Xlog-implicit-conversions" + - option: "-Vimplicits" + schema: + type: "Boolean" + description: "Show more detail on why some implicits are not applicable." + abbreviations: + - "-Xlog-implicits" + - option: "-Vinline" + schema: + type: "String" + arg: "package/Class.method" + default: + description: "Print a summary of inliner activity; `_` to print all, prefix match to select." + abbreviations: + - "-Yopt-log-inline" + - option: "-Vissue" + schema: + type: "Boolean" + description: "Print stack traces when a context issues an error." + abbreviations: + - "-Yissue-debug" + - option: "-Vlog" + schema: + type: "Phases" + default: + description: "Log operations during phases" + abbreviations: + - "-Ylog" + - option: "-Vmacro" + schema: + type: "Boolean" + description: "Trace macro activities: compilation, generation of synthetics, classloading, expansion, exceptions." + abbreviations: + - "-Ymacro-debug-verbose" + - option: "-Vmacro-lite" + schema: + type: "Boolean" + description: "Trace macro activities with less output." + abbreviations: + - "-Ymacro-debug-lite" + - option: "-Vopt" + schema: + type: "String" + arg: "package/Class.method" + default: + description: "Trace the optimizer progress for methods; `_` to print all, prefix match to select." + abbreviations: + - "-Yopt-trace" + - option: "-Vpatmat" + schema: + type: "Boolean" + description: "Trace pattern matching translation." + abbreviations: + - "-Ypatmat-debug" + - option: "-Vphases" + schema: + type: "Boolean" + description: "Print a synopsis of compiler phases." + abbreviations: + - "-Xshow-phases" + - option: "-Vpos" + schema: + type: "Boolean" + description: "Trace position validation." + abbreviations: + - "-Ypos-debug" + - option: "-Vprint" + schema: + type: "Phases" + default: + description: "Print out program after phases" + abbreviations: + - "-Xprint" + - option: "-Vprint-args" + schema: + type: "String" + arg: "file" + default: "-" + description: "Print all compiler arguments to the specified location. Use - to echo to the reporter." + abbreviations: + - "-Xprint-args" + - option: "-Vprint-pos" + schema: + type: "Boolean" + description: "Print tree positions, as offsets." + abbreviations: + - "-Xprint-pos" + - option: "-Vprint-types" + schema: + type: "Boolean" + description: "Print tree types (debugging option)." + abbreviations: + - "-Xprint-types" + - option: "-Vquasiquote" + schema: + type: "Boolean" + description: "Trace quasiquotations." + abbreviations: + - "-Yquasiquote-debug" + - option: "-Vreflective-calls" + schema: + type: "Boolean" + description: "Print a message when a reflective method call is generated" + abbreviations: + - "-Xlog-reflective-calls" + - option: "-Vreify" + schema: + type: "Boolean" + description: "Trace reification." + abbreviations: + - "-Yreify-debug" + - option: "-Vshow" + schema: + type: "Phases" + default: + description: "(Requires -Xshow-class or -Xshow-object) Show after phases" + abbreviations: + - "-Yshow" + - option: "-Vshow-class" + schema: + type: "String" + arg: "class" + default: + description: "Show internal representation of class." + abbreviations: + - "-Xshow-class" + - option: "-Vshow-member-pos" + schema: + type: "String" + arg: "output style" + default: + description: "Show start and end positions of members (implies -Yrangepos)" + abbreviations: + - "-Yshow-member-pos" + - option: "-Vshow-object" + schema: + type: "String" + arg: "object" + default: + description: "Show internal representation of object." + abbreviations: + - "-Xshow-object" + - option: "-Vshow-symkinds" + schema: + type: "Boolean" + description: "Print abbreviated symbol kinds next to symbol names." + abbreviations: + - "-Yshow-symkinds" + - option: "-Vshow-symowners" + schema: + type: "Boolean" + description: "Print owner identifiers next to symbol names." + abbreviations: + - "-Yshow-symowners" + - option: "-Vstatistics" + schema: + type: "Phases" + default: "parser,typer,patmat,erasure,cleanup,jvm" + description: "Print compiler statistics for specific phases phases (default: parser,typer,patmat,erasure,cleanup,jvm)" + abbreviations: + - "-Ystatistics" + - option: "-Vsymbols" + schema: + type: "Boolean" + description: "Print the AST symbol hierarchy after each phase." + abbreviations: + - "-Yshow-syms" + - option: "-Vtyper" + schema: + type: "Boolean" + description: "Trace type assignments." + abbreviations: + - "-Ytyper-debug" - category: "Private Settings" description: options: @@ -568,11 +801,6 @@ schema: type: "Boolean" description: "Attempt to break cycles encountered during typing" - - option: "-Ybrowse" - schema: - type: "Phases" - default: - description: "Browse the abstract syntax tree after phases" - option: "-Ycache-macro-class-loader" schema: type: "Choice" @@ -583,6 +811,8 @@ description: "Don't cache class loader" - choice: "last-modified" description: "Cache class loader, using file last-modified time to invalidate" + - choice: "always" + description: "Cache class loader with no invalidation" description: "Policy for caching class loaders for macros that are dynamically loaded. Default: `none`, `help` to list choices." - option: "-Ycache-plugin-class-loader" schema: @@ -594,6 +824,8 @@ description: "Don't cache class loader" - choice: "last-modified" description: "Cache class loader, using file last-modified time to invalidate" + - choice: "always" + description: "Cache class loader with no invalidation" description: "Policy for caching class loaders for compiler plugins that are dynamically loaded. Default: `none`, `help` to list choices." - option: "-Ycheck" schema: @@ -604,10 +836,6 @@ schema: type: "Boolean" description: "Use compact tree printer when displaying trees." - - option: "-Ydebug" - schema: - type: "Boolean" - description: "Increase the quantity of debugging output." - option: "-Ydelambdafy" schema: type: "Choice" @@ -616,15 +844,7 @@ choices: - choice: "inline" - choice: "method" - description: "Strategy used for translating lambdas into JVM code. Choices: (inline,method), default: method." - - option: "-YdisableFlatCpCaching" - schema: - type: "Boolean" - description: "Do not cache flat classpath representation of classpath elements from jars across compiler instances." - - option: "-Ydoc-debug" - schema: - type: "Boolean" - description: "Trace all scaladoc activity." + description: "Strategy used for translating lambdas into JVM code. (inline,[method])" - option: "-Ydump-classes" schema: type: "String" @@ -637,22 +857,12 @@ arg: "dir" default: description: "Generate a parallel output directory of .asmp files (ie ASM Textifier output)." - - option: "-Yhot-statistics-enabled" - schema: - type: "Boolean" - description: "Enable `-Ystatistics` to print hot statistics." - - option: "-Yide-debug" - schema: - type: "Boolean" - description: "Generate, validate and output trees using the interactive compiler." - - option: "-Yinfer-argument-types" - schema: - type: "Boolean" - description: "Infer types for arguments of overridden methods." - - option: "-Yissue-debug" + - option: "-Yimports" schema: - type: "Boolean" - description: "Print stack traces when a context issues an error." + type: "String" + arg: "import" + multiple: "true" + description: "Custom root imports, default is `java.lang,scala,scala.Predef`." - option: "-Yjar-compression-level" schema: type: "Int" @@ -660,23 +870,16 @@ min: "-1" max: "9" description: "compression level to use when writing jar files" - - option: "-Ylog" - schema: - type: "Phases" - default: - description: "Log operations during phases" - - option: "-Ylog-classpath" - schema: - type: "Boolean" - description: "Output information about what classpath is being applied." - - option: "-Ymacro-debug-lite" + - option: "-Ymacro-annotations" schema: type: "Boolean" - description: "Trace essential macro-related activities." - - option: "-Ymacro-debug-verbose" + description: "Enable support for macro annotations, formerly in macro paradise." + - option: "-Ymacro-classpath" schema: - type: "Boolean" - description: "Trace all macro-related activities: compilation, generation of synthetics, classloading, expansion, exceptions." + type: "Path" + arg: "path" + default: + description: "The classpath used to reflectively load macro implementations, default is the compilation classpath." - option: "-Ymacro-expand" schema: type: "Choice" @@ -686,19 +889,21 @@ - choice: "normal" - choice: "none" - choice: "discard" - description: "Control expansion of macros, useful for scaladoc and presentation compiler. Choices: (normal,none,discard), default: normal." - - option: "-Ymacro-no-expand" - schema: - type: "Boolean" - description: "Don't expand macros. Might be useful for scaladoc and presentation compiler, but will crash anything which uses macros and gets past typer." - - option: "-Yno-adapted-args" + description: "Control expansion of macros, useful for scaladoc and presentation compiler. ([normal],none,discard)" + - option: "-Ymacro-global-fresh-names" schema: type: "Boolean" - description: "Do not adapt an argument list (either by inserting () or creating a tuple) to match the receiver." + description: "Should fresh names in macros be unique across all compilation units" - option: "-Yno-completion" schema: type: "Boolean" description: "Disable tab-completion in the REPL." + - option: "-Yno-flat-classpath-cache" + schema: + type: "Boolean" + description: "Do not cache flat classpath representation of classpath elements from jars across compiler instances." + abbreviations: + - "-YdisableFlatCpCaching" - option: "-Yno-generic-signatures" schema: type: "Boolean" @@ -720,35 +925,7 @@ - choice: "at-inline-annotated" - choice: "everything" - choice: "default" - description: "Set the heuristics for inlining decisions. Choices: (at-inline-annotated,everything,default), default: default." - - option: "-Yopt-log-inline" - schema: - type: "String" - arg: "package/Class.method" - default: - description: "Print a summary of inliner activity; `_` to print all, prefix match to select." - - option: "-Yopt-trace" - schema: - type: "String" - arg: "package/Class.method" - default: - description: "Trace the optimizer progress for methods; `_` to print all, prefix match to select." - - option: "-Yoverride-objects" - schema: - type: "Boolean" - description: "Allow member objects to be overridden." - - option: "-Yoverride-vars" - schema: - type: "Boolean" - description: "Allow vars to be overridden." - - option: "-Ypartial-unification" - schema: - type: "Boolean" - description: "Enable partial unification in type constructor inference" - - option: "-Ypatmat-debug" - schema: - type: "Boolean" - description: "Trace pattern matching translation." + description: "Set the heuristics for inlining decisions. (at-inline-annotated,everything,[default])" - option: "-Ypatmat-exhaust-depth" schema: type: "Int" @@ -756,16 +933,23 @@ min: "10" max: "2147483647" description: "off" - - option: "-Ypos-debug" + - option: "-Yprint-trees" schema: - type: "Boolean" - description: "Trace position validation." + type: "Choice" + arg: "style" + default: "text" + choices: + - choice: "text" + - choice: "compact" + - choice: "format" + - choice: "text+format" + description: "How to print trees when -Vprint is enabled. ([text],compact,format,text+format)" - option: "-Yprofile-destination" schema: type: "String" arg: "file" default: - description: "where to send profiling output - specify a file, default is to the console." + description: "Profiling output - specify a file or `-` for console." - option: "-Yprofile-enabled" schema: type: "Boolean" @@ -780,10 +964,12 @@ type: "Phases" default: "_" description: "Run a GC between phases - this allows heap size to be accurate at the expense of more time. Specify a list of phases, or all phases (default: _)" - - option: "-Yquasiquote-debug" + - option: "-Yprofile-trace" schema: - type: "Boolean" - description: "Trace quasiquote-related activities." + type: "String" + arg: "file" + default: "profile.trace" + description: "Capture trace of compilation in Chrome Trace format" - option: "-Yrangepos" schema: type: "Boolean" @@ -799,10 +985,6 @@ schema: type: "Boolean" description: "Dump the reified trees in copypasteable representation." - - option: "-Yreify-debug" - schema: - type: "Boolean" - description: "Trace reification." - option: "-Yrepl-class-based" schema: type: "Boolean" @@ -813,10 +995,6 @@ arg: "path" default: description: "Write repl-generated classfiles to given output directory (use \"\" to generate a temporary dir)" - - option: "-Yrepl-sync" - schema: - type: "Boolean" - description: "Do not use asynchronous code for repl startup" - option: "-Yresolve-term-conflict" schema: type: "Choice" @@ -826,52 +1004,18 @@ - choice: "package" - choice: "object" - choice: "error" - description: "Resolve term conflicts. Choices: (package,object,error), default: error." - - option: "-Yshow" - schema: - type: "Phases" - default: - description: "(Requires -Xshow-class or -Xshow-object) Show after phases" - - option: "-Yshow-member-pos" + description: "Resolve term conflicts. (package,object,[error])" + - option: "-Yscriptrunner" schema: type: "String" - arg: "output style" - default: - description: "Show start and end positions of members (implies -Yrangepos)" - - option: "-Yshow-symkinds" - schema: - type: "Boolean" - description: "Print abbreviated symbol kinds next to symbol names." - - option: "-Yshow-symowners" - schema: - type: "Boolean" - description: "Print owner identifiers next to symbol names." - - option: "-Yshow-syms" - schema: - type: "Boolean" - description: "Print the AST symbol hierarchy after each phase." - - option: "-Yshow-trees" - schema: - type: "Boolean" - description: "(Requires -Xprint:) Print detailed ASTs in formatted form." - - option: "-Yshow-trees-compact" - schema: - type: "Boolean" - description: "(Requires -Xprint:) Print detailed ASTs in compact form." - - option: "-Yshow-trees-stringified" - schema: - type: "Boolean" - description: "(Requires -Xprint:) Print stringifications along with detailed ASTs." + arg: "classname" + default: "default" + description: "Specify a scala.tools.nsc.ScriptRunner (default, resident, shutdown, or a class name)." - option: "-Yskip" schema: type: "Phases" default: description: "Skip phases" - - option: "-Ystatistics" - schema: - type: "Phases" - default: "parser,typer,patmat,erasure,cleanup,jvm" - description: "Print compiler statistics for specific phases phases (default: parser,typer,patmat,erasure,cleanup,jvm)" - option: "-Ystop-after" schema: type: "Phases" @@ -884,40 +1028,27 @@ type: "Phases" default: description: "Stop before phases" - - option: "-Ytyper-debug" - schema: - type: "Boolean" - description: "Trace all type assignments." - option: "-Yvalidate-pos" schema: type: "Phases" default: description: "Validate positions after the given phases (implies -Yrangepos) phases" - - option: "-Yvirtpatmat" - schema: - type: "Boolean" - description: "Enable pattern matcher virtualization" - - option: "-Ywarn-adapted-args" - schema: - type: "Boolean" - description: "Warn if an argument list is modified to match the receiver." - - option: "-Ywarn-dead-code" +- category: "Warning Settings" + description: + options: + - option: "-Wdead-code" schema: type: "Boolean" description: "Warn when dead code is identified." - - option: "-Ywarn-extra-implicit" + abbreviations: + - "-Ywarn-dead-code" + - option: "-Wextra-implicit" schema: type: "Boolean" description: "Warn when more than one implicit parameter section is defined." - - option: "-Ywarn-inaccessible" - schema: - type: "Boolean" - description: "Warn about inaccessible types in method signatures." - - option: "-Ywarn-infer-any" - schema: - type: "Boolean" - description: "Warn when a type argument is inferred to be `Any`." - - option: "-Ywarn-macros" + abbreviations: + - "-Ywarn-extra-implicit" + - option: "-Wmacros" schema: type: "Choice" arg: "mode" @@ -932,23 +1063,27 @@ - choice: "both" description: "Inspect both user-written code and expanded trees when generating unused symbol warnings." description: "Enable lint warnings on macro expansions. Default: `before`, `help` to list choices." - - option: "-Ywarn-nullary-override" - schema: - type: "Boolean" - description: "Warn when non-nullary `def f()` overrides nullary `def f`." - - option: "-Ywarn-nullary-unit" + abbreviations: + - "-Ywarn-macros" + - option: "-Wnumeric-widen" schema: type: "Boolean" - description: "Warn when nullary methods return Unit." - - option: "-Ywarn-numeric-widen" + description: "Warn when numerics are widened." + abbreviations: + - "-Ywarn-numeric-widen" + - option: "-Woctal-literal" schema: type: "Boolean" - description: "Warn when numerics are widened." - - option: "-Ywarn-self-implicit" + description: "Warn on obsolete octal syntax." + abbreviations: + - "-Ywarn-octal-literal" + - option: "-Wself-implicit" schema: type: "Boolean" description: "Warn when an implicit resolves to an enclosing self-definition." - - option: "-Ywarn-unused" + abbreviations: + - "-Ywarn-self-implicit" + - option: "-Wunused" schema: type: "Choice" arg: "warning" @@ -967,21 +1102,18 @@ - choice: "implicits" description: "Warn if an implicit parameter is unused." - choice: "params" - description: "Enable -Ywarn-unused:explicits,implicits." + description: "Enable -Wunused:explicits,implicits." - choice: "linted" description: "-Xlint:unused." - description: "Enable or disable specific `unused` warnings: `_` for all, `-Ywarn-unused:help` to list choices." - - option: "-Ywarn-unused-import" - schema: - type: "Boolean" - description: "Warn when imports are unused." - - option: "-Ywarn-value-discard" + description: "Enable or disable specific `unused` warnings" + abbreviations: + - "-Ywarn-unused" + - option: "-Wvalue-discard" schema: type: "Boolean" description: "Warn when non-Unit expression results are unused." -- category: "Warning Settings" - description: - options: + abbreviations: + - "-Ywarn-value-discard" - option: "-Xlint" schema: type: "Choice" @@ -1012,19 +1144,29 @@ description: "Option.apply used implicit view." - choice: "delayedinit-select" description: "Selecting member of DelayedInit." - - choice: "by-name-right-associative" - description: "By-name parameter of right associative operator." - choice: "package-object-classes" description: "Class or object defined in package object." - - choice: "unsound-match" - description: "Pattern match may not be typesafe." - choice: "stars-align" description: "Pattern sequence wildcard must align with sequence component." - choice: "constant" description: "Evaluation of a constant arithmetic expression results in an error." - choice: "unused" - description: "Enable -Ywarn-unused:imports,privates,locals,implicits." - description: "Enable or disable specific warnings: `_` for all, `-Xlint:help` to list choices." + description: "Enable -Wunused:imports,privates,locals,implicits." + - choice: "nonlocal-return" + description: "A return statement used an exception for flow control." + - choice: "implicit-not-found" + description: "Check @implicitNotFound and @implicitAmbiguous messages." + - choice: "serial" + description: "@SerialVersionUID on traits and non-serializable classes." + - choice: "valpattern" + description: "Enable pattern checks in val definitions." + - choice: "eta-zero" + description: "Warn on eta-expansion (rather than auto-application) of zero-ary method." + - choice: "eta-sam" + description: "Warn on eta-expansion to meet a Java-defined functional interface that is not explicitly annotated with @FunctionalInterface." + - choice: "deprecation" + description: "Enable linted deprecations." + description: "Enable recommended warnings" - category: "IDE-specific Settings" description: options: @@ -1063,3 +1205,4 @@ schema: type: "Boolean" description: "Print information about presentation compiler tasks." + From 98ebcab76dcd2ebf0147ff61731543169b597e9f Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Fri, 14 Jun 2019 11:42:52 -0700 Subject: [PATCH 0610/3075] Mention PathResolver --- _overviews/compiler-options/index.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/_overviews/compiler-options/index.md b/_overviews/compiler-options/index.md index aa228ba67d..b27efbaa4f 100644 --- a/_overviews/compiler-options/index.md +++ b/_overviews/compiler-options/index.md @@ -49,6 +49,11 @@ scalac [ ] E.g. `scalac -encoding utf8 -Xfatal-warnings Hello.scala` +Default paths can be listed by running a command line tool: +``` +scala scala.tools.util.PathResolver [ ] +``` + ### Use compiler options with sbt From a078d49a93193a7e405856092dff1725bf596b8f Mon Sep 17 00:00:00 2001 From: Dongxu Wang Date: Sat, 20 Jul 2019 08:08:45 +0800 Subject: [PATCH 0611/3075] Add zh-cn version of landing page. --- _zh-cn/index.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ index.md | 2 +- 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 _zh-cn/index.md diff --git a/_zh-cn/index.md b/_zh-cn/index.md new file mode 100644 index 0000000000..c6b0e0d8d3 --- /dev/null +++ b/_zh-cn/index.md @@ -0,0 +1,69 @@ +--- +layout: inner-page-documentation +title: 文档 +language: zh-cn +partof: documentation +discourse: true + +# Content masthead links +sections: + + - title: "第一步..." + links: + - title: "快速开始" + description: "在电脑上安装Scala然后开始写些Scala代码吧!" + icon: "fa fa-rocket" + link: /getting-started.html + - title: "Scala之旅" + description: "核心语言特性简介" + icon: "fa fa-flag" + link: /tour/tour-of-scala.html + - title: "Java程序员Scala入门" + description: "为具有Java背景的程序员准备的Scala简介" + icon: "fa fa-coffee" + link: /tutorials/scala-for-java-programmers.html + more-resources: + - title: 在线课程、练习和博客 + url: /learn.html + - title: 书籍 + url: /books.html + + - title: "回归用户" + links: + - title: "API" + description: "各个Scala版本的API文档" + icon: "fa fa-file-text" + link: /api/all.html + - title: "总览" + description: "涵盖Scala各种特性的深度分析文档" + icon: "fa fa-database" + link: /overviews/index.html + - title: "风格引导" + description: "深度指导如何写出地道的Scala代码" + icon: "fa fa-bookmark" + link: /style/index.html + - title: "速查" + description: "包含Scala基础语法的速查手册" + icon: "fa fa-list" + link: /cheatsheets/index.html + - title: "Scala常见问题" + description: "Scala语言特性的常见问题及答案" + icon: "fa fa-question-circle" + link: /tutorials/FAQ/index.html + - title: "语言规范" + description: "Scala正式语言规范" + icon: "fa fa-book" + link: http://scala-lang.org/files/archive/spec/2.12/ + + - title: "Scala进展" + links: + - title: "SIPs" + description: "Scala改进过程(Scala Improvement Process),语言及编译器进展" + icon: "fa fa-cogs" + link: /sips/index.html + - title: "SPP" + description: "Scala平台进程(Scala Platform Process), 社区驱动代码库的进展" + icon: "fa fa-users" + link: https://platform.scala-lang.org + +--- diff --git a/index.md b/index.md index fb6d93db53..7f1527e81a 100644 --- a/index.md +++ b/index.md @@ -1,7 +1,7 @@ --- layout: inner-page-documentation title: Documentation -languages: [ja] +languages: [ja, zh-cn] namespace: root partof: documentation discourse: true From 1228f6497cf8141658695f07bbd807ba43be27e2 Mon Sep 17 00:00:00 2001 From: Miron Aseev Date: Sat, 20 Jul 2019 11:18:53 +0700 Subject: [PATCH 0612/3075] Remove the redundant 'val' and 'new' keywords --- _ba/tour/operators.md | 4 ++-- _ja/tour/operators.md | 4 ++-- _ru/tour/operators.md | 4 ++-- _tour/operators.md | 4 ++-- _zh-cn/tour/operators.md | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/_ba/tour/operators.md b/_ba/tour/operators.md index 363cf74858..1f68f621a7 100644 --- a/_ba/tour/operators.md +++ b/_ba/tour/operators.md @@ -29,8 +29,8 @@ Međutim, lakše je čitati kada se napiše kao infiksni operator: Možete koristiti bilo koji legalni identifikator kao operator. To uključuje i imena kao `add` ili simbole kao `+`. ```tut -case class Vec(val x: Double, val y: Double) { - def +(that: Vec) = new Vec(this.x + that.x, this.y + that.y) +case class Vec(x: Double, y: Double) { + def +(that: Vec) = Vec(this.x + that.x, this.y + that.y) } val vector1 = Vec(1.0, 1.0) diff --git a/_ja/tour/operators.md b/_ja/tour/operators.md index e6c2352ef2..f5b1ac6ed5 100644 --- a/_ja/tour/operators.md +++ b/_ja/tour/operators.md @@ -29,8 +29,8 @@ Scalaでは演算子はメソッドです。パラメータを1つだけ持つ 有効な識別子であれば演算子として使用できます。これは `add`のような名前も`+`のような記号も含みます。 ```tut -case class Vec(val x: Double, val y: Double) { - def +(that: Vec) = new Vec(this.x + that.x, this.y + that.y) +case class Vec(x: Double, y: Double) { + def +(that: Vec) = Vec(this.x + that.x, this.y + that.y) } val vector1 = Vec(1.0, 1.0) diff --git a/_ru/tour/operators.md b/_ru/tour/operators.md index 1609ce60f5..33b4cbfd20 100644 --- a/_ru/tour/operators.md +++ b/_ru/tour/operators.md @@ -26,8 +26,8 @@ prerequisite-knowledge: case-classes ## Создание и использование операторов В качестве оператора можно использовать любой допустимый символ. Включая имена на подобии `add` или символ (символы) типа `+`. ```tut -case class Vec(val x: Double, val y: Double) { - def +(that: Vec) = new Vec(this.x + that.x, this.y + that.y) +case class Vec(x: Double, y: Double) { + def +(that: Vec) = Vec(this.x + that.x, this.y + that.y) } val vector1 = Vec(1.0, 1.0) diff --git a/_tour/operators.md b/_tour/operators.md index b3ad662813..5744213cc0 100644 --- a/_tour/operators.md +++ b/_tour/operators.md @@ -26,8 +26,8 @@ However, it's easier to read as an infix operator: ## Defining and using operators You can use any legal identifier as an operator. This includes a name like `add` or a symbol(s) like `+`. ```tut -case class Vec(val x: Double, val y: Double) { - def +(that: Vec) = new Vec(this.x + that.x, this.y + that.y) +case class Vec(x: Double, y: Double) { + def +(that: Vec) = Vec(this.x + that.x, this.y + that.y) } val vector1 = Vec(1.0, 1.0) diff --git a/_zh-cn/tour/operators.md b/_zh-cn/tour/operators.md index c662d3a80c..dc42357bc8 100644 --- a/_zh-cn/tour/operators.md +++ b/_zh-cn/tour/operators.md @@ -26,8 +26,8 @@ previous-page: type-inference ## 定义和使用运算符 你可以使用任何合法标识符作为运算符。 包括像 `add` 这样的名字或像 `+` 这样的符号。 ```tut -case class Vec(val x: Double, val y: Double) { - def +(that: Vec) = new Vec(this.x + that.x, this.y + that.y) +case class Vec(x: Double, y: Double) { + def +(that: Vec) = Vec(this.x + that.x, this.y + that.y) } val vector1 = Vec(1.0, 1.0) From a6500c6d0e99016311473853dc2d8ebf54efba01 Mon Sep 17 00:00:00 2001 From: Flakeparadigm Date: Sat, 20 Jul 2019 13:10:36 +1000 Subject: [PATCH 0613/3075] Update Style Guide TOC and Method Invocation page --- _style/index.md | 9 ++-- _style/method-invocation.md | 96 ++++++++++++++++++++++++------------- 2 files changed, 67 insertions(+), 38 deletions(-) diff --git a/_style/index.md b/_style/index.md index 29ae8d16b5..8fed2138bb 100644 --- a/_style/index.md +++ b/_style/index.md @@ -54,11 +54,10 @@ This document is intended to outline some basic Scala stylistic guidelines which - [Trivial Conditionals](control-structures.html#trivial-conditionals) - [Method Invocation](method-invocation.html) - [Arity-0](method-invocation.html#arity-0) - - [Infix Notation](method-invocation.html#infix-notation) - - [Postfix Notation](method-invocation.html) - - [Arity-1](method-invocation.html) - - [Higher-Order Functions](method-invocation.html) - - [Symbolic methods/Operators](method-invocation.html) + - [Postfix Notation](method-invocation.html#postfix-notation) + - [Arity-1 (Infix Notation)](method-invocation.html#arity-1-infix-notation) + - [Symbolic Methods/Operators](method-invocation.html#symbolic-methodsoperators) + - [Higher-Order Functions](method-invocation.html#higher-order-functions) - [Files](files.html) - [Multi-Unit Files](files.html#multi-unit-files) - [Scaladoc](scaladoc.html) diff --git a/_style/method-invocation.md b/_style/method-invocation.md index bb9fdb3fb9..5b0b5099ea 100644 --- a/_style/method-invocation.md +++ b/_style/method-invocation.md @@ -56,22 +56,36 @@ readability and will make it much easier to understand at a glance the most basic operation of any given method. Resist the urge to omit parentheses simply to save two characters! -## Infix notation +### Postfix Notation -Scala has a special punctuation-free syntax for invoking methods that -take one argument. Many Scala programmers use this notation for -symbolic-named methods: +Scala allows methods that take no arguments to be invoked using postfix notation: // recommended - a + b + names.toList - // legal, but less readable - a+b + // discourage + names toList - // legal, but definitely strange - a.+(b) +This style is unsafe, and should not be used. Since semicolons are +optional, the compiler will attempt to treat it as an infix method +if it can, potentially taking a term from the next line. -but avoid it for almost all alphabetic-named methods: + names toList + val answer = 42 // will not compile! + +This may result in unexpected compile errors at best, and happily +compiled faulty code at worst. Although the syntax is used by some +DSLs, it should be considered deprecated, and avoided. + +Since Scala 2.10, using postfix operator notation will result in a +compiler warning. + +## Arity-1 (Infix Notation) + +Scala has a special punctuation-free syntax for invoking methods of arity-1 +(one argument). This should generally be avoided, but with the following +exceptions for operators and higher-order functions. In these cases it should +only be used for purely-functional methods (methods with no side-effects). // recommended names.mkString(",") @@ -79,8 +93,25 @@ but avoid it for almost all alphabetic-named methods: // also sometimes seen; controversial names mkString "," -A gray area is short, operator-like methods like `max`, -especially if commutative: + // wrong - has side-effects + javaList add item + +### Symbolic Methods/Operators + +Symbolic methods (operators) should always be invoked using infix notation with +spaces separating the target, the operator, and the parameter: + + // right! + "daniel" + " " + "spiewak" + a + b + + // wrong! + "daniel"+" "+"spiewak" + a+b + a.+(b) + +For the most part, this idiom follows Java and Haskell syntactic conventions. A +gray area is short, operator-like methods like `max`, especially if commutative: // fairly common a max b @@ -90,31 +121,30 @@ may still be invoked using infix notation, delimited by spaces: foo ** (bar, baz) -Such methods are fairly rare, however, and should normally be avoided -during API design. For example, the use of the `/:` and `:\` methods -should be avoided in preference to their better-known names, -`foldLeft` and `foldRight`. - -## Postfix Notation +Such methods are fairly rare, however, and should normally be avoided during API +design. For example, the use of the `/:` and `:\` methods should be avoided in +preference to their better-known names, `foldLeft` and `foldRight`. -Scala allows methods that take no arguments to be invoked using postfix notation: +### Higher-Order Functions - // recommended - names.toList +As noted, methods which take functions as parameters (such as `map` or +`foreach`) should be invoked using infix notation. It is also *possible* to +invoke such methods in the following way: - // discourage - names toList + // wrong! + names.map { _.toUpperCase } -This style is unsafe, and should not be used. Since semicolons are -optional, the compiler will attempt to treat it as an infix method -if it can, potentially taking a term from the next line. +This style is *not* the accepted standard! The reason to avoid this style is for +situations where more than one invocation must be chained together: - names toList - val answer = 42 // will not compile! + // wrong! + names.map { _.toUpperCase }.filter { _.length > 5 } -This may result in unexpected compile errors at best, and happily -compiled faulty code at worst. Although the syntax is used by some -DSLs, it should be considered deprecated, and avoided. + // right! + names map { _.toUpperCase } filter { _.length > 5 } -Since Scala 2.10, using postfix operator notation will result in a -compiler warning. +Both of these work, but the former can easily lead to confusion. The +sub-expression `{ _.toUpperCase }.filter` when taken in isolation looks like we +are invoking the `filter` method on a function value. However, we are actually +invoking `filter` on the result of the `map` method, which takes the function +value as a parameter. From 0d03cba3440e0048d5b2221b1f0f33cb55b66485 Mon Sep 17 00:00:00 2001 From: Flakeparadigm Date: Sat, 20 Jul 2019 15:22:38 +1000 Subject: [PATCH 0614/3075] Ensure Style guide overview and TOC match --- _style/control-structures.md | 2 +- _style/declarations.md | 12 ++++++------ _style/files.md | 6 +++--- _style/index.md | 5 +++-- _style/method-invocation.md | 2 +- _style/nested-blocks.md | 2 +- _style/scaladoc.md | 2 +- 7 files changed, 16 insertions(+), 15 deletions(-) diff --git a/_style/control-structures.md b/_style/control-structures.md index df74036aee..7a746c46bd 100644 --- a/_style/control-structures.md +++ b/_style/control-structures.md @@ -7,7 +7,7 @@ overview-name: "Style Guide" num: 7 -previous-page: files +previous-page: declarations next-page: method-invocation --- diff --git a/_style/declarations.md b/_style/declarations.md index 90708e4b1b..b8cdb75c7f 100644 --- a/_style/declarations.md +++ b/_style/declarations.md @@ -5,10 +5,10 @@ title: Declarations partof: style overview-name: "Style Guide" -num: 9 +num: 6 -previous-page: method-invocation -next-page: scaladoc +previous-page: nested-blocks +next-page: control-structures --- ## Classes @@ -51,7 +51,7 @@ empty line should be added to further separate extensions from class implementat with Logging with Identifiable with Serializable { - + def firstMethod: Foo = … } @@ -286,11 +286,11 @@ function value. When styles (1) and (4) are used exclusively, it becomes very easy to distinguish places in the source code where function values are used. -Both styles make use of parentheses, since they look clean on a single line. +Both styles make use of parentheses, since they look clean on a single line. ### Spacing -There should be no space between parentheses and the code they contain. +There should be no space between parentheses and the code they contain. Curly braces should be separated from the code within them by a one-space gap, to give the visually busy braces "breathing room". diff --git a/_style/files.md b/_style/files.md index 668ac3c82b..54ddf4e2db 100644 --- a/_style/files.md +++ b/_style/files.md @@ -5,10 +5,10 @@ title: Files partof: style overview-name: "Style Guide" -num: 6 +num: 9 -previous-page: nested-blocks -next-page: control-structures +previous-page: method-invocation +next-page: scaladoc --- As a rule, files should contain a *single* logical compilation unit. By diff --git a/_style/index.md b/_style/index.md index 8fed2138bb..df59d51944 100644 --- a/_style/index.md +++ b/_style/index.md @@ -31,7 +31,7 @@ This document is intended to outline some basic Scala stylistic guidelines which - [Annotations](types.html#annotations) - [Ascription](types.html#ascription) - [Functions](types.html#functions) - - [Arity-1](types.html) + - [Arity-1](types.html#arity-1) - [Structural Types](types.html#structural-types) - [Nested Blocks](nested-blocks.html) - [Curly Braces](nested-blocks.html#curly-braces) @@ -40,10 +40,11 @@ This document is intended to outline some basic Scala stylistic guidelines which - [Classes](declarations.html#classes) - [Ordering Of Class Elements](declarations.html#ordering-of-class-elements) - [Methods](declarations.html#methods) + - [Procedure Syntax](declarations.html#procedure-syntax) - [Modifiers](declarations.html#modifiers) - [Body](declarations.html#body) - [Multiple Parameter Lists](declarations.html#multiple-parameter-lists) - - [Higher-Order Functions](declarations.html) + - [Higher-Order Functions](declarations.html#higher-order-functions) - [Fields](declarations.html#fields) - [Function Values](declarations.html#function-values) - [Spacing](declarations.html#spacing) diff --git a/_style/method-invocation.md b/_style/method-invocation.md index 5b0b5099ea..694552afba 100644 --- a/_style/method-invocation.md +++ b/_style/method-invocation.md @@ -8,7 +8,7 @@ overview-name: "Style Guide" num: 8 previous-page: control-structures -next-page: declarations +next-page: files --- Generally speaking, method invocation in Scala follows Java conventions. diff --git a/_style/nested-blocks.md b/_style/nested-blocks.md index 3c489da966..6970f050f9 100644 --- a/_style/nested-blocks.md +++ b/_style/nested-blocks.md @@ -8,7 +8,7 @@ overview-name: "Style Guide" num: 5 previous-page: types -next-page: files +next-page: declarations --- ## Curly Braces diff --git a/_style/scaladoc.md b/_style/scaladoc.md index 6ce4b63fef..7a78bd713f 100644 --- a/_style/scaladoc.md +++ b/_style/scaladoc.md @@ -7,7 +7,7 @@ overview-name: "Style Guide" num: 10 -previous-page: declarations +previous-page: files --- It is important to provide documentation for all packages, classes, From 81b316edabeb8efcbfb2ba2945fabe5f31e94d30 Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 20 Jul 2019 11:49:56 +0900 Subject: [PATCH 0615/3075] Add Japanese translation of Getting Started. --- ...g-a-scala-project-with-intellij-and-sbt.md | 101 ++++++++++++++++++ .../getting-started-with-scala-in-intellij.md | 73 +++++++++++++ ...esting-scala-in-intellij-with-scalatest.md | 71 ++++++++++++ ...-with-scala-and-sbt-on-the-command-line.md | 89 +++++++++++++++ ...ting-scala-with-sbt-on-the-command-line.md | 71 ++++++++++++ _ja/getting-started.md | 52 +++++++++ ...g-a-scala-project-with-intellij-and-sbt.md | 2 + .../getting-started-with-scala-in-intellij.md | 2 + ...esting-scala-in-intellij-with-scalatest.md | 2 + ...-with-scala-and-sbt-on-the-command-line.md | 2 + ...ting-scala-with-sbt-on-the-command-line.md | 2 + getting-started.md | 2 + 12 files changed, 469 insertions(+) create mode 100644 _ja/getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.md create mode 100644 _ja/getting-started-intellij-track/getting-started-with-scala-in-intellij.md create mode 100644 _ja/getting-started-intellij-track/testing-scala-in-intellij-with-scalatest.md create mode 100644 _ja/getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md create mode 100644 _ja/getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.md create mode 100644 _ja/getting-started.md diff --git a/_ja/getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.md b/_ja/getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.md new file mode 100644 index 0000000000..7059ff70f2 --- /dev/null +++ b/_ja/getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.md @@ -0,0 +1,101 @@ +--- +title: Intellij で sbt を使って Scala プロジェクトをビルドする +layout: singlepage-overview +partof: building-a-scala-project-with-intellij-and-sbt +language: ja +disqus: true +previous-page: /ja/getting-started-intellij-track/getting-started-with-scala-in-intellij +next-page: /ja/testing-scala-in-intellij-with-scalatest +--- + +このチュートリアルでは、[sbt](http://www.scala-sbt.org/1.x/docs/index.html) を使って Scala プロジェクトをビルドする方法を見ていきます。 +sbtは、どのようなサイズの Scala プロジェクトでもコンパイル、実行、テストできる人気のツールです。 +sbt(または Maven や Gradle)のようなビルドツールの使用は、1つ以上のコードファイルや依存関係のあるプロジェクトを作ったら、絶対不可欠になります。 +[最初のチュートリアル](./getting-started-with-scala-in-intellij.html)を完了していることを前提とします。 + +## プロジェクトを作成 +このでは、Intellij でプロジェクトの作り方をお見せします。 +ですが、コマンドラインのほうが快適でしたら、[Getting +コマンドラインの sbt で Scala を始める](/ja/getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.html) を試して、「Scala コードを記述」節に戻ってくるのをおすすめします。 + +1. コマンドラインからプロジェクトを作っていなければ、Intellij を開き、"Create New Project" を選びます。 + * 左パネルで Scala を選び、右パネルで sbt を選びます。 + * **Next** をクリックします + * プロジェクトに **SbtExampleProject** と名前を付けます。 +1. コマンドラインですでにプロジェクトを作成していたら、Intelij を開き、**Import Project** を選んで、あなたのプロジェクトの `build.sbt` ファイルを開きます。 +1. **JDK version** が `1.8` で、**sbt version** が少なくとも `0.13.13` であることを確認します。 +1. **Use auto-import** を選びます。すると依存関係が利用可能であれば自動でダウンロードされます。 +1. **Finish** を選びます。 + +## ディレクトリ構造を理解 + +sbt は、より複雑なプロジェクトを構築すだしたら便利になるであろう多くのディレクトリを作成します。 +今はそのほとんどを無視できますが、全部が何のためかをここでちらっと見ておきましょう。 + +``` +- .idea (IntelliJ ファイル) +- project (sbt のプラグインや追加設定) +- src (ソースファイル) + - main (アプリケーションコード) + - java (Java ソースファイル) + - scala (Scala ソースファイル) + ^-- 今はこれが必要なものの全てです + - scala-2.12 (Scala 2.12 固有ファイル) + - test (ユニットテスト) +- target (生成されたファイル) +- build.sbt (sbt のためのビルド定義ファイル) +``` + + +## Scala コードを記述 +1. 左の **Project** パネルで、`SbtExampleProject` => `src` => `main` を展開します。 +1. `scala` を右クリックし、**New** => **Package** を選択します。 +1. パッケージに `example` と名前をつけ、**OK** をクリックします。 +1. パッケージ `example` を右クリックし、**New** => **Scala class** をクリックします。 +1. クラスに `Main` と名前をつけ、**Kind** を `object` に変更します。 +1. クラスのコードを次おように変更します。 + +``` +object Main extends App { + val ages = Seq(42, 75, 29, 64) + println(s"The oldest person is ${ages.max}") +} +``` + +注:Intellij は Scala コンパイラーの独自実装を持っており、コードが間違っていると Intellij が示しても正しい場合がときどきあります。 +コマンドラインで sbt がプロジェクトを実行できるかを常にチェックできます。。 + +## プロジェクトを実行 +1. **Run** メニューから、**Edit configurations** を選びます。 +1. **+** ボタンをクリックし、**sbt Task** を選びます +1. それに `Run the program` と名付けます。 +1. **Tasks** フィールドで、`~run` と入力します. + `~` は、プロジェクトファイルへの変更を保存するたびに sbt にプロジェクトを再ビルド、再実行させます。 +1. **OK** をクリックします。 +1. **Run** メニューで、**Run 'Run the program'** をクリックします。 +1. コードの `75` を `61` に変えて、コンソールで更新された出力を見ます。 + +## 依存関係を追加 + +趣向を少し変えて、アプリに追加機能を加えるために公開ライブラリの使い方を見てみましょう。 + +`build.sbt` を開き、以下のファイルを追加します。 + +``` +libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.0" +``` + +ここで `libraryDependencies` は依存関係の集合であり、`+=` を使うことにより、[scala-parser-combinators](https://github.com/scala/scala-parser-combinators) への依存を、sbt が起動時に取得してくる依存関係の集合に加えています。 +これで、どの Scala ファイルでも、`scala-parser-combinator` にあるクラスやオブジェクトなどを通常のインポートでインポートできます。 + +さらなる公開ライブラリは、Scala ライブラリインデックス [Scaladex](https://index.scala-lang.org/) で見つけられます。 +そこでは上述のような依存関係情報をコピーでき、`build.sbt` ファイルにペーストできます。 + +## 次のステップ + +**Intellij で入門** シリーズの次のチュートリアルに進み、[Intelij で ScalaTest を使って Scala をテストする](testing-scala-in-intellij-with-scalatest.html)方法を学びます。 + +**あるいは** + +- インタラクティブなオンラインコース [Scala Exercises](https://www.scala-exercises.org/scala_tutorial) で Scala を学習します。 +- [Scala ツアー](/ja//tour/tour-of-scala.html) で Scala の特徴を一口大のサイズでステップバイステップに学びます。 diff --git a/_ja/getting-started-intellij-track/getting-started-with-scala-in-intellij.md b/_ja/getting-started-intellij-track/getting-started-with-scala-in-intellij.md new file mode 100644 index 0000000000..676c247d40 --- /dev/null +++ b/_ja/getting-started-intellij-track/getting-started-with-scala-in-intellij.md @@ -0,0 +1,73 @@ +--- +title: Intellij で Scala を始める +layout: singlepage-overview +partof: getting-started-with-scala-in-intellij +language: ja +disqus: true +next-page: /ja/building-a-scala-project-with-intellij-and-sbt +--- + +このチュートリアルでは、Intellij IDEA と Scala プラグインを使って最小限の Scala プロジェクトを作る方法を見ていきます。 +このガイドでは、Intellij があなたのために Scala をダウンロードしてくれます。 + +## インストール +1. Java 8 JDK(別名 1.8)がインストールされていることを確認します。 + * コマンドラインで `javac -version` を実行し、`javac 1.8.___` と表示されるのを確認します。 + * バージョン 1.8 かそれ以上がなければ、[JDK をインストールします](https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)。 +1. [IntelliJ Community Edition](https://www.jetbrains.com/idea/download/) をダウンロード、インストールします。 +1. それから、Intellij を起動したあと、[how to install IntelliJ plugins](https://www.jetbrains.com/help/idea/installing-updating-and-uninstalling-repository-plugins.html) の指示に従って Scala プラグインをダウンロードしてインストールできます(プラグインメニューで「Scala」と検索)。 + +プロジェクトを作るときは、Scala の最新バージョンをインストールします。 +注:存在する Scala プロジェクトを開きたければ、Intellij をスタートするときに **Open** をクリックします。 + + +## プロジェクトを作成 +1. Intellij を開き、**File** => **New** => **Project** をクリックします。 +1. 左パネルで Scala を選びます。右のパネルで IDEA を開きます。 +1. プロジェクトに **HelloWorld** と名前を付けます。 +1. 今回始めて Intellij で Scala プロジェクトを初めて作るとすれば、Scala SDK をインストールする必要があります。Scala SDK フィールドの右側にある **Create** ボタンをクリックします。 +1. 最新のバージョン番号(例 {{ site.scala-version }})を選び、**Download**をクリックします。 + これは数分かかるかもしれませんが、今後のプロジェクトでは同じ SDK を使えます。 +1. SDK がダウンロードされたらすぐに、「New Project」ウィンドウに戻って **Finish** ボタンをクリックします。 + + +## コードを記述 + +1. 左側の **プロジェクト** ペインで、`src` ディレクトリを右クリックし、**New** => **Scala class** を選択します。 + もし、**Scala class** が見当たらなければ、**HelloWorld** を右クリックし、**Add Framework Support...** をクリックし、**Scala** を選択して進めます。 + **Error: library is not specified** が発生したら、ダウンロードボタンをクリックするか、またはライブラリパスを手動で選択します。 +1. クラスに `Hello` と名前を付けて、**Kind** を `object` に変更します。 +1. クラスのコードを次のように変更します。 + +``` +object Hello extends App { + println("Hello, World!") +} +``` + +## 実行 +* あなたのコード `Hello` で右クリックし、**Run 'Hello'** を選びます。 +* 完了です! + +## Scala を試してみる + +コード例を試してみる良い方法は、Scala ワークシートです。 + +1. 左のプロジェクトペインで、`src` ディレクトリを右クリックし、**New** => **Scala Worksheet** を選びます。 +2. 新しい Scala ワークシートに "Mathematician" と名前を付けます。 +3. ワークシートに以下のコードを入力します。 + +``` +def square(x: Int) = x * x + +square(2) +``` + +コードを変更するにつれて、その評価結果が右ペインに現れるのに気づくでしょう。 + +## 次のステップ + +言語を学び始めるのに使える、シンプルな Scala プロジェクトの作り方を学びました。 +次のチュートリアルでは、シンプルなプロジェクトから本番アプリケーションまで使える sbt という重要なビルドツールを紹介します。 + +次: [Intellij で sbt を使って Scala プロジェクトをビルドする](building-a-scala-project-with-intellij-and-sbt.html) diff --git a/_ja/getting-started-intellij-track/testing-scala-in-intellij-with-scalatest.md b/_ja/getting-started-intellij-track/testing-scala-in-intellij-with-scalatest.md new file mode 100644 index 0000000000..e2cedcac86 --- /dev/null +++ b/_ja/getting-started-intellij-track/testing-scala-in-intellij-with-scalatest.md @@ -0,0 +1,71 @@ +--- +title: Intelij で ScalaTest を使って Scala をテストする +layout: singlepage-overview +partof: testing-scala-in-intellij-with-scalatest +language: ja +disqus: true +previous-page: /ja/building-a-scala-project-with-intellij-and-sbt +--- + +Scala には複数のライブラリとテスト方法がありますが、このチュートリアルでは、ScalaTest フレームワークから [FunSuite](http://www.scalatest.org/getting_started_with_fun_suite) という人気のある選択肢を実演します。 + +[Intellij で sbt を使って Scala プロジェクトをビルドする方法](./building-a-scala-project-with-intellij-and-sbt.html)を知っている前提とします。 + +## セットアップ +1. Intellij で sbt プロジェクトを作成します。 +1. ScalaTest への依存を追加します。 + 1. `build.sbt` ファイルに ScalaTest への依存を追加します。 + ``` + libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test" + ``` + 1. `build.sbt was changed` という通知が出たら、**auto-import** を選択します。 + 1. これらの2つのアクションにより、`sbt` が ScalaTest ライブラリをダウンロードします。 + 1. `sbt` の同期完了を待ちます。そうしなければ `FunSuite` と `test()` は認識されません。 +1. 左のプロジェクトペインで、`src` => `main` を展開します。 +1. `scala` を右クリックし、**New** => **Scala class** を選択します。 +1. クラスに `CubeCalculator` と名前をつけて、**Kind** を `object` に変更し、**OK** をクリックします。 +1. コードを次の通り置き換えます。 + ``` + object CubeCalculator extends App { + def cube(x: Int) = { + x * x * x + } + } + ``` + +## テストを作成 +1. 左のプロジェクトペインで、`src` => `test` を展開します。 +1. `scala` を右クリックし、**New** => **Scala class** を選択します。 +1. クラスに `CubeCalculatorTest` と名前を付けて、**OK** をクリックします。 +1. コードを次の通り置き換えます。 + ``` + import org.scalatest.FunSuite + + class CubeCalculatorTest extends FunSuite { + test("CubeCalculator.cube") { + assert(CubeCalculator.cube(3) === 27) + } + } + ``` +1. `CubeCalculatorTest` のソースコード内で右クリックし、**Run 'CubeCalculatorTest'** を選択します。 + +## コードを理解 + +一行ずつ詳細に調べていきましょう。 + +* `class CubeCalculatorTest` は、オブジェクト `CubeCalculator` をテストすることを意味します。 +* `extends FunSuite` により、ScalaTest の FunSuite クラスの機能(例えば `test` 関数)が使えるようになります。 +* `test` は FunSuite から来た関数で、関数本体内のアサーションの結果を収集します。 +* `"CubeCalculator.cube"` は、テストの名前です。 + どんな名前でもよいですが、慣例のひとつは "ClassName.methodName" です。 +* `assert` は、真偽値の条件を1つ受けとり、そのテストが合格するか失敗するかを判断します。 +* `CubeCalculator.cube(3) === 27` は `cube` 関数の結果が実際に 27 であるかどうかを調べます。 + `===` は ScalaTest の一部であり、きれいなエラーメッセージを提供します。 + +## テストケースを追加する +1. 1つ目の `assert` 句のあとにもう1つの句を追加し、`0` の3乗をチェックします。 +1. `CubeCalculatorTest` を右クリックして 'Run **CubeCalculatorTest**' を選ぶことで、テストを再実行します。 + +## 結び +Scala コードのテスト方法のひとつを見ました。 +ScalaTest の FunSuite については[公式ウェブサイト](http://www.scalatest.org/getting_started_with_fun_suite)で詳しく学べます。 diff --git a/_ja/getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md b/_ja/getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md new file mode 100644 index 0000000000..e87db4bd38 --- /dev/null +++ b/_ja/getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md @@ -0,0 +1,89 @@ +--- +title: コマンドラインの sbt で Scala を始める +layout: singlepage-overview +partof: getting-started-with-scala-and-sbt-on-the-command-line +language: ja +disqus: true +next-page: /ja/testing-scala-with-sbt-on-the-command-line +--- + +このチュートリアルでは、テンプレートから Scala プロジェクトを作成する方法を見ていきます。 +あなた自身のプロジェクトを始めるスタート地点として使えます。 +Scala のデファクトのビルドツール [sbt](http://www.scala-sbt.org/1.x/docs/index.html) を用います。 +sbt はあなたのプロジェクトに関連した様々なタスク、とりわけコンパイル、実行、テストをしてくれます。 +ターミナルの使い方を知っていることを前提とします。 + +## インストール +1. Java 8 JDK(別名 1.8)がインストールされていることを確認します。 + * コマンドラインで `javac -version` を実行し、`javac 1.8.___` と表示されるのを確認します。 + * バージョン 1.8 かそれ以上がなければ、[JDK をインストールします](https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html)。 +1. sbt をインストールします。 + * [Mac](http://www.scala-sbt.org/1.x/docs/Installing-sbt-on-Mac.html) + * [Windows](http://www.scala-sbt.org/1.x/docs/Installing-sbt-on-Windows.html) + * [Linux](http://www.scala-sbt.org/1.x/docs/Installing-sbt-on-Linux.html) + +## プロジェクトを作成 +1. `cd` to an empty folder. +1. Run the following command `sbt new scala/hello-world.g8`. +This pulls the 'hello-world' template from GitHub. +It will also create a `target` folder, which you can ignore. +1. When prompted, name the application `hello-world`. This will +create a project called "hello-world". +1. Let's take a look at what just got generated: + +``` +- hello-world + - project (sbt uses this to install manage plugins and dependencies) + - build.properties + - src + - main + - scala (All of your scala code goes here) + -Main.scala (Entry point of program) <-- this is all we need for now + build.sbt (sbt's build definition file) +``` + +After you build your project, sbt will create more `target` directories +for generated files. You can ignore these. + +## Running the project +1. `cd` into `hello-world`. +1. Run `sbt`. This will open up the sbt console. +1. Type `~run`. The `~` is optional and causes sbt to re-run on every file save, +allowing for a fast edit/run/debug cycle. sbt will also generate a `target` directory +which you can ignore. + +## Modifying the code +1. Open the file `src/main/scala/Main.scala` in your favorite text editor. +1. Change "Hello, World!" to "Hello, New York!" +1. If you haven't stopped the sbt command, you should see "Hello, New York!" +printed to the console. +1. You can continue to make changes and see the results in the console. + +## Adding a dependency +Changing gears a bit, let's look at how to use published libraries to add +extra functionality to our apps. + +1. Open up `build.sbt` and add the following line: + +``` +libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.0" +``` +Here, `libraryDependencies` is a set of dependencies, and by using `+=`, +we're adding the [scala-parser-combinators](https://github.com/scala/scala-parser-combinators) dependency to the set of dependencies that sbt will go +and fetch when it starts up. Now, in any Scala file, you can import classes, +objects, etc, from scala-parser-combinators with a regular import. + +You can find more published libraries on +[Scaladex](https://index.scala-lang.org/), the Scala library index, where you +can also copy the above dependency information for pasting into your `build.sbt` +file. + +## Next steps + +Continue to the next tutorial in the _getting started with sbt_ series, and learn about [testing Scala code with sbt in the command line](testing-scala-with-sbt-on-the-command-line.html). + +**or** + +- Continue learning Scala interactively online on + [Scala Exercises](https://www.scala-exercises.org/scala_tutorial). +- Learn about Scala's features in bite-sized pieces by stepping through our [Tour of Scala]({{ site.baseurl }}/tour/tour-of-scala.html). diff --git a/_ja/getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.md b/_ja/getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.md new file mode 100644 index 0000000000..0c2d7f1a42 --- /dev/null +++ b/_ja/getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.md @@ -0,0 +1,71 @@ +--- +title: コマンドラインで ScalaTest を使って Scala をテストする +layout: singlepage-overview +partof: testing-scala-with-sbt-on-the-command-line +language: ja +disqus: true +previous-page: /ja/getting-started-with-scala-and-sbt-on-the-command-line +--- + +Scala には複数のライブラリとテスト方法がありますが、このチュートリアルでは、ScalaTest フレームワークから [FunSuite](http://www.scalatest.org/getting_started_with_fun_suite) という人気のある選択肢を実演します。 + +[sbt での Scala プロジェクト作成方法](/getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.html)を知っている前提とします。 + +## セットアップ +1. コマンドラインで、どこかに新しいディレクトリを作成します。 +1. そのディレクトリに `cd` して、`sbt new scala/scalatest-example.g8` を実行します。 +1. プロジェクトに `ScalaTestTutorial` と名前を付けます。 +1. ScalaTest が依存関係として `build.sbt` ファイルに書かれたプロジェクトができます。. +1. そのディレクトリに `cd` して、`sbt test` を実行します。 + これは `CubeCalculator.cube` という1つのテストを含むテストスイート `CubeCalculatorTest` を実行します。 + +``` +sbt test +[info] Loading global plugins from /Users/username/.sbt/0.13/plugins +[info] Loading project definition from /Users/username/workspace/sandbox/my-something-project/project +[info] Set current project to scalatest-example (in build file:/Users/username/workspace/sandbox/my-something-project/) +[info] CubeCalculatorTest: +[info] - CubeCalculator.cube +[info] Run completed in 267 milliseconds. +[info] Total number of tests run: 1 +[info] Suites: completed 1, aborted 0 +[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0 +[info] All tests passed. +[success] Total time: 1 s, completed Feb 2, 2017 7:37:31 PM +``` + +## テストを理解 +1. テキストエディタで2つのファイルを開きます。 + * `src/main/scala/CubeCalculator.scala` + * `src/test/scala/CubeCalculatorTest.scala` +1. `CubeCalculator.scala` ファイルでは、関数 `cube` がどのように定義されているかが分かります。 +1. `CubeCalculatorTest.scala` ファイルでは、テスト対象オブジェクトにちなんで名前を付けられたクラスが見えます。 + +``` + import org.scalatest.FunSuite + + class CubeCalculatorTest extends FunSuite { + test("CubeCalculator.cube") { + assert(CubeCalculator.cube(3) === 27) + } + } +``` + +一行ずつ詳細に調べていきましょう。 + +* `class CubeCalculatorTest` は、オブジェクト `CubeCalculator` をテストすることを意味します。 +* `extends FunSuite` により、ScalaTest の FunSuite クラスの機能(例えば `test` 関数)が使えるようになります。 +* `test` は FunSuite から来た関数で、関数本体内のアサーションの結果を収集します。 +* `"CubeCalculator.cube"` は、テストの名前です。 + どんな名前でもよいですが、慣例のひとつは "ClassName.methodName" です。 +* `assert` は、真偽値の条件を1つ受けとり、そのテストが合格するか失敗するかを判断します。 +* `CubeCalculator.cube(3) === 27` は `cube` 関数の結果が実際に 27 であるかどうかを調べます。 + `===` は ScalaTest の一部であり、きれいなエラーメッセージを提供します。 + +## テストケースを追加する +1. 1つ目の `assert` 句のあとにもう1つの句を追加し、`0` の3乗をチェックします。 +1. `sbt test` を再び実行し、結果を見ます。 + +## 結び +Scala コードのテスト方法のひとつを見ました。 +ScalaTest の FunSuite については[公式ウェブサイト](http://www.scalatest.org/getting_started_with_fun_suite)で詳しく学べます。 diff --git a/_ja/getting-started.md b/_ja/getting-started.md new file mode 100644 index 0000000000..1f02d1588b --- /dev/null +++ b/_ja/getting-started.md @@ -0,0 +1,52 @@ +--- +layout: singlepage-overview +title: 入門 +partof: getting-started +language: ja +includeTOC: true +--- + +
Scala の取り組み方で人々に好まれている主な方法は 2つ あります。
+ +1. IDE を使う +2. コマンドラインを使う + +以下のチュートリアルでは、どちらかお好みの方法をセットアップする一連のプロセスを通して行っていきます。 + +ですが、もし何もインストールせずに直接 Scala に飛び込んでみたければ、このページのガイドは飛ばして、以下をチェックしてみましょう。 + +* [scala-exercises.com での Scala のインタラクティブな導入](https://www.scala-exercises.org/scala_tutorial/terms_and_types) +* [Scastie](https://scastie.scala-lang.org/)。ブラウザで動く Scalaで、すべての Scala コンパイラと公開されたライブラリにアクセス可能。 + +## セットアップして Scala に入門 + +### IDE で取り組むのをお好みの場合 + +Intellij は、Scala 開発者にもっともよく使われている IDE です。 +このチュートリアルでは、Intellij をダウンロードして Scala プラグインをセットアップするまでを通して行い、それから初めての Scala プロジェクトを開始して、ユニットテストを完了させます! + +* [Intellij で Scala を始める](/ja/getting-started-intellij-track/getting-started-with-scala-in-intellij.html) +* [Intellij で sbt を使って Scala プロジェクトをビルドする](/ja/getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.html) +* [Intelij で ScalaTest を使って Scala をテストする](/ja/getting-started-intellij-track/testing-scala-in-intellij-with-scalatest.html) + + +### コマンドラインで取り組むのをお好みの場合 + +emacs、Vim、Atom、Sublime Text のようなテキストエディターの使用がお好みでしたら、Scala コードをコンパイル、テスト、実行する最良の方法は、**sbt**(Scala build tool) を使うことです。 + +* [コマンドラインの sbt で Scala を始める](/ja/getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.html) +* [コマンドラインで ScalaTest を使って Scala をテストする](/ja/getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.html) + +## 次のステップ + +このチュートリアルを終えたら、次をチェックしてみましょう。 + +* [Scala ツアー](/ja/tour/tour-of-scala.html)は、Scala の特徴を簡単に理解できるサイズで紹介します。 +* [学習リソース](/learn.html)(英語のみ)は、オンラインのインタラクティブなチュートリアルや教材を紹介します。 +* [Scala の人気書籍一覧](/books.html)(訳注:英語のみですが、邦訳されたものもあります)。 + +## 助けを求めるには + +他の Scala ユーザーとすばやくつながりたいとときには、メーリングリストやリアルタイムのチャットチャンネルがたくさんあります。 +こうしたリソースや助けを求められる場所を一覧できる [community](https://scala-lang.org/community/) ページをチェックしてみてください。 + diff --git a/getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.md b/getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.md index 021aed1bbf..860adfcc5f 100644 --- a/getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.md +++ b/getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.md @@ -1,6 +1,8 @@ --- title: Building a Scala Project with IntelliJ and sbt layout: singlepage-overview +partof: building-a-scala-project-with-intellij-and-sbt +languages: [ja] disqus: true previous-page: getting-started-intellij-track/getting-started-with-scala-in-intellij next-page: testing-scala-in-intellij-with-scalatest diff --git a/getting-started-intellij-track/getting-started-with-scala-in-intellij.md b/getting-started-intellij-track/getting-started-with-scala-in-intellij.md index 730f2e7f36..bfe19ca864 100644 --- a/getting-started-intellij-track/getting-started-with-scala-in-intellij.md +++ b/getting-started-intellij-track/getting-started-with-scala-in-intellij.md @@ -1,6 +1,8 @@ --- title: Getting Started with Scala in IntelliJ layout: singlepage-overview +partof: getting-started-with-scala-in-intellij +languages: [ja] disqus: true next-page: building-a-scala-project-with-intellij-and-sbt --- diff --git a/getting-started-intellij-track/testing-scala-in-intellij-with-scalatest.md b/getting-started-intellij-track/testing-scala-in-intellij-with-scalatest.md index 93a9574272..a517067bfc 100644 --- a/getting-started-intellij-track/testing-scala-in-intellij-with-scalatest.md +++ b/getting-started-intellij-track/testing-scala-in-intellij-with-scalatest.md @@ -1,6 +1,8 @@ --- title: Testing Scala in IntelliJ with ScalaTest layout: singlepage-overview +partof: testing-scala-in-intellij-with-scalatest +languages: [ja] disqus: true previous-page: building-a-scala-project-with-intellij-and-sbt --- diff --git a/getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md b/getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md index 0c69c6595f..12dca3b8ba 100644 --- a/getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md +++ b/getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md @@ -1,6 +1,8 @@ --- title: Getting Started with Scala and sbt on the Command Line layout: singlepage-overview +partof: getting-started-with-scala-and-sbt-on-the-command-line +languages: [ja] disqus: true next-page: testing-scala-with-sbt-on-the-command-line --- diff --git a/getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.md b/getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.md index ba38a030ee..8c9d74b23b 100644 --- a/getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.md +++ b/getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.md @@ -1,6 +1,8 @@ --- title: Testing Scala with sbt and ScalaTest on the Command Line layout: singlepage-overview +partof: testing-scala-with-sbt-on-the-command-line +languages: [ja] disqus: true previous-page: getting-started-with-scala-and-sbt-on-the-command-line --- diff --git a/getting-started.md b/getting-started.md index fb392d5344..2808703712 100644 --- a/getting-started.md +++ b/getting-started.md @@ -1,6 +1,8 @@ --- layout: singlepage-overview title: Getting Started +partof: getting-started +languages: [ja] includeTOC: true --- From eade469c24073ad18fb1153485a34a3010cfdefe Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 20 Jul 2019 11:50:09 +0900 Subject: [PATCH 0616/3075] Update link to ja/getting-started --- _ja/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_ja/index.md b/_ja/index.md index 4f22939227..1cbc83b784 100644 --- a/_ja/index.md +++ b/_ja/index.md @@ -11,9 +11,9 @@ sections: - title: "最初のステップ" links: - title: "入門" - description: "あなたのコンピューターに Scala をインストールして、Scala コードを書きはじめよう!(英語のみ)" + description: "あなたのコンピューターに Scala をインストールして、Scala コードを書きはじめよう!" icon: "fa fa-rocket" - link: /getting-started.html + link: /ja/getting-started.html - title: "Scala ツアー" description: "コア言語機能をひと口大で紹介" icon: "fa fa-flag" From 988a18fc89efe2fd58e2a67e9780256b9576cd5a Mon Sep 17 00:00:00 2001 From: exoego Date: Sat, 20 Jul 2019 11:57:48 +0900 Subject: [PATCH 0617/3075] Move "Getting Started" and sub pages into collection, so that it site.documents finds them. --- _config.yml | 3 +++ _data/doc-nav-header.yml | 2 +- .../index.md | 18 ++++++++++-------- ...ng-a-scala-project-with-intellij-and-sbt.md | 6 ++++-- .../getting-started-with-scala-in-intellij.md | 2 ++ ...testing-scala-in-intellij-with-scalatest.md | 2 ++ ...d-with-scala-and-sbt-on-the-command-line.md | 2 ++ ...sting-scala-with-sbt-on-the-command-line.md | 2 ++ _includes/sidebar-toc-singlepage-overview.html | 2 +- .../index.md} | 10 +++++----- ...ng-a-scala-project-with-intellij-and-sbt.md | 4 ++-- .../getting-started-with-scala-in-intellij.md | 0 ...testing-scala-in-intellij-with-scalatest.md | 0 ...d-with-scala-and-sbt-on-the-command-line.md | 0 ...sting-scala-with-sbt-on-the-command-line.md | 2 +- _ja/index.md | 2 +- _overviews/scaladoc/generate.md | 2 +- 17 files changed, 37 insertions(+), 22 deletions(-) rename getting-started.md => _getting-started/index.md (70%) rename {getting-started-intellij-track => _getting-started/intellij-track}/building-a-scala-project-with-intellij-and-sbt.md (95%) rename {getting-started-intellij-track => _getting-started/intellij-track}/getting-started-with-scala-in-intellij.md (97%) rename {getting-started-intellij-track => _getting-started/intellij-track}/testing-scala-in-intellij-with-scalatest.md (97%) rename {getting-started-sbt-track => _getting-started/sbt-track}/getting-started-with-scala-and-sbt-on-the-command-line.md (97%) rename {getting-started-sbt-track => _getting-started/sbt-track}/testing-scala-with-sbt-on-the-command-line.md (97%) rename _ja/{getting-started.md => getting-started/index.md} (90%) rename _ja/{getting-started-intellij-track => getting-started/intellij-track}/building-a-scala-project-with-intellij-and-sbt.md (97%) rename _ja/{getting-started-intellij-track => getting-started/intellij-track}/getting-started-with-scala-in-intellij.md (100%) rename _ja/{getting-started-intellij-track => getting-started/intellij-track}/testing-scala-in-intellij-with-scalatest.md (100%) rename _ja/{getting-started-sbt-track => getting-started/sbt-track}/getting-started-with-scala-and-sbt-on-the-command-line.md (100%) rename _ja/{getting-started-sbt-track => getting-started/sbt-track}/testing-scala-with-sbt-on-the-command-line.md (98%) diff --git a/_config.yml b/_config.yml index 320c7a9839..b2c1f4ffa9 100644 --- a/_config.yml +++ b/_config.yml @@ -37,6 +37,9 @@ collections: permalink: /:collection/:path.html books: output: false + getting-started: + output: true + permalink: /:collection/:path.html ja: # Japanese translations output: true permalink: /:collection/:path.html diff --git a/_data/doc-nav-header.yml b/_data/doc-nav-header.yml index f7a4ff3ea2..f46ecfe93b 100644 --- a/_data/doc-nav-header.yml +++ b/_data/doc-nav-header.yml @@ -11,7 +11,7 @@ url: "#" submenu: - title: Getting Started - url: "/getting-started.html" + url: "/getting-started/index.html" - title: Tour of Scala url: "/tour/tour-of-scala.html" - title: Scala for Java Programmers diff --git a/getting-started.md b/_getting-started/index.md similarity index 70% rename from getting-started.md rename to _getting-started/index.md index 2808703712..2680e32d83 100644 --- a/getting-started.md +++ b/_getting-started/index.md @@ -4,6 +4,8 @@ title: Getting Started partof: getting-started languages: [ja] includeTOC: true + +redirect_from: "/getting-started.html" ---
There are two main ways people prefer to work in Scala.
@@ -33,9 +35,9 @@ we'll walk you through downloading and setting up IntelliJ with the Scala plugin, and we'll get you started with your first Scala project, complete with unit tests! -* [Getting Started with Scala in IntelliJ](getting-started-intellij-track/getting-started-with-scala-in-intellij.html) -* [Building a Scala Project with IntelliJ and sbt](getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.html) -* [Testing Scala in IntelliJ with ScalaTest](getting-started-intellij-track/testing-scala-in-intellij-with-scalatest.html) +* [Getting Started with Scala in IntelliJ](/getting-started/intellij-track/getting-started-with-scala-in-intellij.html) +* [Building a Scala Project with IntelliJ and sbt](/getting-started/intellij-track/building-a-scala-project-with-intellij-and-sbt.html) +* [Testing Scala in IntelliJ with ScalaTest](/getting-started/intellij-track/testing-scala-in-intellij-with-scalatest.html) ### If you prefer working on the command line... @@ -44,8 +46,8 @@ If you prefer using a text editor like emacs, Vim, Atom, or Sublime Text, then the best way to compile, test, and run Scala code is using _sbt_, Scala's build tool. -* [Getting Started with Scala and sbt on the Command Line](getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.html) -* [Testing Scala with sbt and ScalaTest on the Command Line](getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.html) +* [Getting Started with Scala and sbt on the Command Line](/getting-started/sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.html) +* [Testing Scala with sbt and ScalaTest on the Command Line](/getting-started/sbt-track/testing-scala-with-sbt-on-the-command-line.html) ## Next Steps Once you've finished these tutorials, check out -* [The Tour of Scala](tour/tour-of-scala.html) for bite-sized introductions to Scala's features. -* [Learning Resources](learn.html), which includes online interactive tutorials and courses. -* [Our list of some popular Scala books](books.html). +* [The Tour of Scala](/tour/tour-of-scala.html) for bite-sized introductions to Scala's features. +* [Learning Resources](/learn.html), which includes online interactive tutorials and courses. +* [Our list of some popular Scala books](/books.html). ## Getting Help There are a multitude of mailing lists and real-time chat channels in case you want to quickly connect with other Scala users. Check out our [community](https://scala-lang.org/community/) page a list of these resources and where to reach out for help. diff --git a/getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.md b/_getting-started/intellij-track/building-a-scala-project-with-intellij-and-sbt.md similarity index 95% rename from getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.md rename to _getting-started/intellij-track/building-a-scala-project-with-intellij-and-sbt.md index 860adfcc5f..622ebc61fd 100644 --- a/getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.md +++ b/_getting-started/intellij-track/building-a-scala-project-with-intellij-and-sbt.md @@ -4,8 +4,10 @@ layout: singlepage-overview partof: building-a-scala-project-with-intellij-and-sbt languages: [ja] disqus: true -previous-page: getting-started-intellij-track/getting-started-with-scala-in-intellij +previous-page: getting-started/intellij-track/getting-started-with-scala-in-intellij next-page: testing-scala-in-intellij-with-scalatest + +redirect_from: "/getting-started-intellij-track/building-a-scala-project-with-intellij-and-sbt.html" --- In this tutorial, we'll see how to build a Scala project using [sbt](http://www.scala-sbt.org/1.x/docs/index.html). sbt is a popular tool for compiling, running, and testing Scala projects of any @@ -17,7 +19,7 @@ or more than one code file. ## Creating the project In this section, we'll show you how to create the project in IntelliJ. However, if you're comfortable with the command line, we recommend you try [Getting -Started with Scala and sbt on the Command Line]({{site.baseurl}}/getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.html) and then come back +Started with Scala and sbt on the Command Line]({{site.baseurl}}/getting-started/sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.html) and then come back here to the section "Writing Scala code". 1. If you didn't create the project from the command line, open up IntelliJ and select "Create New Project" diff --git a/getting-started-intellij-track/getting-started-with-scala-in-intellij.md b/_getting-started/intellij-track/getting-started-with-scala-in-intellij.md similarity index 97% rename from getting-started-intellij-track/getting-started-with-scala-in-intellij.md rename to _getting-started/intellij-track/getting-started-with-scala-in-intellij.md index bfe19ca864..a4544a707e 100644 --- a/getting-started-intellij-track/getting-started-with-scala-in-intellij.md +++ b/_getting-started/intellij-track/getting-started-with-scala-in-intellij.md @@ -5,6 +5,8 @@ partof: getting-started-with-scala-in-intellij languages: [ja] disqus: true next-page: building-a-scala-project-with-intellij-and-sbt + +redirect_from: "/getting-started-intellij-track/getting-started-with-scala-in-intellij.html" --- In this tutorial, we'll see how to build a minimal Scala project using IntelliJ diff --git a/getting-started-intellij-track/testing-scala-in-intellij-with-scalatest.md b/_getting-started/intellij-track/testing-scala-in-intellij-with-scalatest.md similarity index 97% rename from getting-started-intellij-track/testing-scala-in-intellij-with-scalatest.md rename to _getting-started/intellij-track/testing-scala-in-intellij-with-scalatest.md index a517067bfc..bf895167e2 100644 --- a/getting-started-intellij-track/testing-scala-in-intellij-with-scalatest.md +++ b/_getting-started/intellij-track/testing-scala-in-intellij-with-scalatest.md @@ -5,6 +5,8 @@ partof: testing-scala-in-intellij-with-scalatest languages: [ja] disqus: true previous-page: building-a-scala-project-with-intellij-and-sbt + +redirect_from: "/getting-started-intellij-track/testing-scala-in-intellij-with-scalatest.html" --- There are multiple libraries and testing methodologies for Scala, diff --git a/getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md b/_getting-started/sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md similarity index 97% rename from getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md rename to _getting-started/sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md index 12dca3b8ba..64c6fdb5fa 100644 --- a/getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md +++ b/_getting-started/sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md @@ -5,6 +5,8 @@ partof: getting-started-with-scala-and-sbt-on-the-command-line languages: [ja] disqus: true next-page: testing-scala-with-sbt-on-the-command-line + +redirect_from: "/getting-started-sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.html" --- In this tutorial, you'll see how to create a Scala project from diff --git a/getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.md b/_getting-started/sbt-track/testing-scala-with-sbt-on-the-command-line.md similarity index 97% rename from getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.md rename to _getting-started/sbt-track/testing-scala-with-sbt-on-the-command-line.md index 8c9d74b23b..9a3d4507b9 100644 --- a/getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.md +++ b/_getting-started/sbt-track/testing-scala-with-sbt-on-the-command-line.md @@ -5,6 +5,8 @@ partof: testing-scala-with-sbt-on-the-command-line languages: [ja] disqus: true previous-page: getting-started-with-scala-and-sbt-on-the-command-line + +redirect_from: "/getting-started-sbt-track/testing-scala-with-sbt-on-the-command-line.html" --- There are multiple libraries and testing methodologies for Scala, diff --git a/_includes/sidebar-toc-singlepage-overview.html b/_includes/sidebar-toc-singlepage-overview.html index d8fa5c3ede..bcea6a8911 100644 --- a/_includes/sidebar-toc-singlepage-overview.html +++ b/_includes/sidebar-toc-singlepage-overview.html @@ -15,7 +15,7 @@
Contents
{% elsif page.language %} {% assign engPath = page.id | remove_first: "/" | remove_first: page.language | append: '.html' %} - {% assign engPg = site.overviews | where: 'partof', page.partof | first %} + {% assign engPg = site.documents | where: 'partof', page.partof | first %}
{% endfor %} diff --git a/_sass/layout/overviews.scss b/_sass/layout/overviews.scss index 930502116b..39058ef40f 100644 --- a/_sass/layout/overviews.scss +++ b/_sass/layout/overviews.scss @@ -47,12 +47,10 @@ position: relative; flex: 0 1 calc(50% - 1em); margin-bottom: 2em; - transition: max-height .3s ease-out; text-decoration: none; border-radius: 2px; box-shadow: 0 1px 3px 0 rgba(0,0,0,.2), 0 1px 1px 0 rgba(0,0,0,.14), 0 2px 1px -1px rgba(0,0,0,.12); background: #fff; - max-height: 400px; overflow: hidden; @include bp(medium) { @@ -76,7 +74,7 @@ .card-content { padding: 20px; padding-top: 0px; - padding-bottom: 0px; + padding-bottom: 60px; } h2 { @@ -160,25 +158,23 @@ position: absolute; bottom: 0; width: 100%; - padding: 20px; - height: 66px; - background: #fff; - border-top: 1px solid lighten($base-font-color-light, 35%); - - &:hover { - cursor: pointer; - background: $brand-primary; - .expand-btn, - .go-btn { - color: #fff; - } - } - .expand-btn, .go-btn { - color: lighten($base-font-color-light, 15%); + display: block; + padding: 20px; + height: 66px; + background: #fff; + border-top: 1px solid lighten($base-font-color-light, 35%); + color: lighten($base-font-color-light, 10%); font-weight: $font-regular; font-size: $font-regular; + text-decoration: none; + + &:hover { + cursor: pointer; + background: $brand-primary; + color: #fff; + } } } } diff --git a/resources/js/functions.js b/resources/js/functions.js index 3d7ff70428..046ec1a7f5 100644 --- a/resources/js/functions.js +++ b/resources/js/functions.js @@ -133,30 +133,6 @@ $(document).ready(function() { return false; }; - - $('.white-card').each(function(index) { - if (!$(this).hasOverflow()) { - $(this).find(".expand-btn").hide(); - $(this).find(".go-btn").show(); - } - }); - - $(".card-footer").click(function() { - // if we clicked on the expand button, expand the box - if ($(this).find(".expand-btn").is(':visible')) { - - // height mangling becasue flexbox align-self: self-end; doesn't work :( - $(this).parent().css('max-height', 'none'); - var cardWrapHeight = $(this).parent().find(".card-wrap").outerHeight(); - var cardFooterHeight = $(this).outerHeight() - $(this).parent().outerHeight(cardWrapHeight + cardFooterHeight); - - $(this).find(".expand-btn").hide(); - $(this).find(".go-btn").show(); - } else { - window.location.href = $(this).find(".go-btn").attr("href"); - } - }); }); From ad9ccd05ee688afba00c1f9181e6dedb51737271 Mon Sep 17 00:00:00 2001 From: exoego Date: Mon, 22 Jul 2019 14:03:51 +0900 Subject: [PATCH 0620/3075] Add subtitle so user/crawler know the group the page belongs to. --- _includes/headertop.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/_includes/headertop.html b/_includes/headertop.html index e39ab97d51..de2b123d50 100644 --- a/_includes/headertop.html +++ b/_includes/headertop.html @@ -1,7 +1,11 @@ - {% if page.title %}{{ page.title }} | {% endif %}{{ site.title }} + + {% if page.title %}{{ page.title }} | {% endif %} + {% if page.overview-name %}{{ page.overview-name }} | {% endif %} + {{ site.title }} + {% if page.description %} {% endif %} From 290ac29e58b5809e4326060f3036f9b262cdea0c Mon Sep 17 00:00:00 2001 From: wooruang Date: Tue, 23 Jul 2019 07:43:42 +0900 Subject: [PATCH 0621/3075] Translate tuples.md and Modify the 'num' of elements in tour docs (#1403) --- _ko/tour/case-classes.md | 2 +- _ko/tour/higher-order-functions.md | 2 +- _ko/tour/mixin-class-composition.md | 2 +- _ko/tour/multiple-parameter-lists.md | 2 +- _ko/tour/nested-functions.md | 2 +- _ko/tour/pattern-matching.md | 2 +- _ko/tour/singleton-objects.md | 2 +- _ko/tour/tuples.md | 74 ++++++++++++++++++++++++++-- 8 files changed, 77 insertions(+), 11 deletions(-) diff --git a/_ko/tour/case-classes.md b/_ko/tour/case-classes.md index 6d32c6bac2..5823edd55f 100644 --- a/_ko/tour/case-classes.md +++ b/_ko/tour/case-classes.md @@ -6,7 +6,7 @@ discourse: false partof: scala-tour -num: 10 +num: 11 language: ko next-page: pattern-matching diff --git a/_ko/tour/higher-order-functions.md b/_ko/tour/higher-order-functions.md index 40adfba248..cfd1decc91 100644 --- a/_ko/tour/higher-order-functions.md +++ b/_ko/tour/higher-order-functions.md @@ -6,7 +6,7 @@ discourse: false partof: scala-tour -num: 7 +num: 8 language: ko next-page: nested-functions diff --git a/_ko/tour/mixin-class-composition.md b/_ko/tour/mixin-class-composition.md index e4d2cac40f..0f6f1b8a54 100644 --- a/_ko/tour/mixin-class-composition.md +++ b/_ko/tour/mixin-class-composition.md @@ -6,7 +6,7 @@ discourse: false partof: scala-tour -num: 6 +num: 7 language: ko next-page: higher-order-functions diff --git a/_ko/tour/multiple-parameter-lists.md b/_ko/tour/multiple-parameter-lists.md index 03d6e171ec..49d514be94 100644 --- a/_ko/tour/multiple-parameter-lists.md +++ b/_ko/tour/multiple-parameter-lists.md @@ -6,7 +6,7 @@ discourse: false partof: scala-tour -num: 9 +num: 10 language: ko next-page: case-classes diff --git a/_ko/tour/nested-functions.md b/_ko/tour/nested-functions.md index 9f55347977..8d9126e7ce 100644 --- a/_ko/tour/nested-functions.md +++ b/_ko/tour/nested-functions.md @@ -6,7 +6,7 @@ discourse: false partof: scala-tour -num: 8 +num: 9 language: ko next-page: multiple-parameter-lists diff --git a/_ko/tour/pattern-matching.md b/_ko/tour/pattern-matching.md index 9be1ac47e4..64063ee003 100644 --- a/_ko/tour/pattern-matching.md +++ b/_ko/tour/pattern-matching.md @@ -6,7 +6,7 @@ discourse: false partof: scala-tour -num: 11 +num: 12 language: ko next-page: singleton-objects diff --git a/_ko/tour/singleton-objects.md b/_ko/tour/singleton-objects.md index daff154256..339d05fc1a 100644 --- a/_ko/tour/singleton-objects.md +++ b/_ko/tour/singleton-objects.md @@ -6,7 +6,7 @@ discourse: false partof: scala-tour -num: 12 +num: 13 language: ko next-page: regular-expression-patterns diff --git a/_ko/tour/tuples.md b/_ko/tour/tuples.md index 4463425bee..476aa69d6b 100644 --- a/_ko/tour/tuples.md +++ b/_ko/tour/tuples.md @@ -1,17 +1,83 @@ --- layout: tour -title: Tuples +title: 튜플 discourse: true partof: scala-tour -num: + +num: 6 language: ko next-page: mixin-class-composition previous-page: traits +topics: tuples +redirect_from: "/tutorials/tour/tuples.html" --- -(this section of the tour has not been translated yet. pull request -with translation welcome!) \ No newline at end of file +스칼라에서 튜플은 정해진 요소(element)를 가지는 값으로 각 요소는 고유한 타입을 가진다. 튜플은 불변적이다. + +튜플은 특히 메소드로부터 여러개의 값을 리턴하는데 편리하게 사용할 수 있다. + +두개의 엘리먼트를 갖는 튜플은 다음과 같이 생성할 수 있다: + +```tut +val ingredient = ("Sugar" , 25) +``` + +위 코드는 `String`과 `Int` 엘리먼트를 포함하는 튜플을 생성한다. + +`ingredient`의 추론된 타입은 `Tuple2[String, Int]`의 약칭인 `(String, Int)`이다. + +튜플들을 나타내기 위해서 Scala에서는 다음과 같은 형태의 클래스들을 사용한다: `Tuple2`, `Tuple3`, ... ,`Tuple22`. +각 클래스는 파라미터 타입의 갯수 만큼 엘리먼트들을 가지고 있다. + +## 엘리먼트 접근하기 + +튜플의 엘리먼트에 접근하기 위한 한가지 방법은 위치로 접근하는 것이다. 각 요소들은 `_1`, `_2`, ... 와 같은 이름을 갖는다. + +```tut +println(ingredient._1) // Sugar +println(ingredient._2) // 25 +``` + +## 튜플에서의 패턴 매칭 + +하나의 튜플은 패턴 매칭을 사용하여 분리할 수 있다: + +```tut +val (name, quantity) = ingredient +println(name) // Sugar +println(quantity) // 25 +``` + +여기에서 `name`의 추론된 타입은 `String`이고 `quantity`의 추론된 타입은 `Int`이다. + +여기 튜플을 패턴 매칭한 또 다른 예제가 있다: + +```tut +val planets = + List(("Mercury", 57.9), ("Venus", 108.2), ("Earth", 149.6), + ("Mars", 227.9), ("Jupiter", 778.3)) +planets.foreach{ + case ("Earth", distance) => + println(s"Our planet is $distance million kilometers from the sun") + case _ => +} +``` + +또는 `for` comprehension에서: + +```tut +val numPairs = List((2, 5), (3, -7), (20, 56)) +for ((a, b) <- numPairs) { + println(a * b) +} +``` + +## 튜플과 케이스 클래스 + +때로는 튜플과 케이스 클래스 중 무엇을 사용할지 힘들 수 있다. 케이스 클래스는 이름이 있는 엘리먼트들을 갖는다. 그 엘리먼트의 이름들은 어떤 종류의 코드에서 가독성을 높일 수 있다. 위의 planet 예제에서 우리는 튜플을 사용하는 것보다 `case class Planet(name: String, distance: Double)`로 정의 하는 것이 더 나을 수도 있다. + +이한샘 옮김 From f3cde7e6ee36b56b1d9af7c2a13622b8f00ccc48 Mon Sep 17 00:00:00 2001 From: exoego Date: Mon, 22 Jul 2019 13:44:52 +0900 Subject: [PATCH 0622/3075] Mark older Overviews/Collections --- _overviews/collections/arrays.md | 2 +- _overviews/collections/concrete-immutable-collection-classes.md | 2 +- _overviews/collections/concrete-mutable-collection-classes.md | 2 +- .../conversions-between-java-and-scala-collections.md | 2 +- _overviews/collections/creating-collections-from-scratch.md | 2 +- _overviews/collections/equality.md | 2 +- _overviews/collections/introduction.md | 2 +- _overviews/collections/iterators.md | 2 +- _overviews/collections/maps.md | 2 +- _overviews/collections/migrating-from-scala-27.md | 2 +- _overviews/collections/overview.md | 2 +- _overviews/collections/performance-characteristics.md | 2 +- _overviews/collections/seqs.md | 2 +- _overviews/collections/sets.md | 2 +- _overviews/collections/strings.md | 2 +- _overviews/collections/trait-iterable.md | 2 +- _overviews/collections/trait-traversable.md | 2 +- _overviews/collections/views.md | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) diff --git a/_overviews/collections/arrays.md b/_overviews/collections/arrays.md index 343ebb1c74..bce565ea14 100644 --- a/_overviews/collections/arrays.md +++ b/_overviews/collections/arrays.md @@ -5,7 +5,7 @@ title: Arrays discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 10 diff --git a/_overviews/collections/concrete-immutable-collection-classes.md b/_overviews/collections/concrete-immutable-collection-classes.md index b0e16eceb7..3f1fad4378 100644 --- a/_overviews/collections/concrete-immutable-collection-classes.md +++ b/_overviews/collections/concrete-immutable-collection-classes.md @@ -5,7 +5,7 @@ title: Concrete Immutable Collection Classes discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 8 diff --git a/_overviews/collections/concrete-mutable-collection-classes.md b/_overviews/collections/concrete-mutable-collection-classes.md index 432eb6df9f..2e7e94e988 100644 --- a/_overviews/collections/concrete-mutable-collection-classes.md +++ b/_overviews/collections/concrete-mutable-collection-classes.md @@ -5,7 +5,7 @@ title: Concrete Mutable Collection Classes discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 9 diff --git a/_overviews/collections/conversions-between-java-and-scala-collections.md b/_overviews/collections/conversions-between-java-and-scala-collections.md index 7d1f3d150a..7c7323125c 100644 --- a/_overviews/collections/conversions-between-java-and-scala-collections.md +++ b/_overviews/collections/conversions-between-java-and-scala-collections.md @@ -5,7 +5,7 @@ title: Conversions Between Java and Scala Collections discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 17 diff --git a/_overviews/collections/creating-collections-from-scratch.md b/_overviews/collections/creating-collections-from-scratch.md index cdff42e054..d21c13d710 100644 --- a/_overviews/collections/creating-collections-from-scratch.md +++ b/_overviews/collections/creating-collections-from-scratch.md @@ -5,7 +5,7 @@ title: Creating Collections From Scratch discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 16 diff --git a/_overviews/collections/equality.md b/_overviews/collections/equality.md index 0e41a5ccd9..08a8d110eb 100644 --- a/_overviews/collections/equality.md +++ b/_overviews/collections/equality.md @@ -5,7 +5,7 @@ title: Equality discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 13 diff --git a/_overviews/collections/introduction.md b/_overviews/collections/introduction.md index e026efafaa..c480affa85 100644 --- a/_overviews/collections/introduction.md +++ b/_overviews/collections/introduction.md @@ -5,7 +5,7 @@ title: Introduction discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 1 diff --git a/_overviews/collections/iterators.md b/_overviews/collections/iterators.md index 975824d498..02a41f1ed0 100644 --- a/_overviews/collections/iterators.md +++ b/_overviews/collections/iterators.md @@ -5,7 +5,7 @@ title: Iterators discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 15 diff --git a/_overviews/collections/maps.md b/_overviews/collections/maps.md index 89a0663914..d7291dc6cb 100644 --- a/_overviews/collections/maps.md +++ b/_overviews/collections/maps.md @@ -5,7 +5,7 @@ title: Maps discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 7 diff --git a/_overviews/collections/migrating-from-scala-27.md b/_overviews/collections/migrating-from-scala-27.md index 87f557ca4f..939ef0987c 100644 --- a/_overviews/collections/migrating-from-scala-27.md +++ b/_overviews/collections/migrating-from-scala-27.md @@ -5,7 +5,7 @@ title: Migrating from Scala 2.7 discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 18 diff --git a/_overviews/collections/overview.md b/_overviews/collections/overview.md index 41bdf6ff39..b4c73e0567 100644 --- a/_overviews/collections/overview.md +++ b/_overviews/collections/overview.md @@ -5,7 +5,7 @@ title: Mutable and Immutable Collections discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 2 diff --git a/_overviews/collections/performance-characteristics.md b/_overviews/collections/performance-characteristics.md index c43aeabb68..e6e1e92537 100644 --- a/_overviews/collections/performance-characteristics.md +++ b/_overviews/collections/performance-characteristics.md @@ -5,7 +5,7 @@ title: Performance Characteristics discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 12 diff --git a/_overviews/collections/seqs.md b/_overviews/collections/seqs.md index 3e12de6fc1..a932a8ce4b 100644 --- a/_overviews/collections/seqs.md +++ b/_overviews/collections/seqs.md @@ -5,7 +5,7 @@ title: The sequence traits Seq, IndexedSeq, and LinearSeq discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 5 diff --git a/_overviews/collections/sets.md b/_overviews/collections/sets.md index 4b06a0501f..d93a03acad 100644 --- a/_overviews/collections/sets.md +++ b/_overviews/collections/sets.md @@ -5,7 +5,7 @@ title: Sets discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 6 diff --git a/_overviews/collections/strings.md b/_overviews/collections/strings.md index b1729328de..058fb8b281 100644 --- a/_overviews/collections/strings.md +++ b/_overviews/collections/strings.md @@ -5,7 +5,7 @@ title: Strings discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 11 diff --git a/_overviews/collections/trait-iterable.md b/_overviews/collections/trait-iterable.md index e478f3d4d7..f8f0bf7763 100644 --- a/_overviews/collections/trait-iterable.md +++ b/_overviews/collections/trait-iterable.md @@ -5,7 +5,7 @@ title: Trait Iterable discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 4 diff --git a/_overviews/collections/trait-traversable.md b/_overviews/collections/trait-traversable.md index fe048347ec..a954246f99 100644 --- a/_overviews/collections/trait-traversable.md +++ b/_overviews/collections/trait-traversable.md @@ -5,7 +5,7 @@ title: Trait Traversable discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 3 diff --git a/_overviews/collections/views.md b/_overviews/collections/views.md index 09e5b8f7ff..2a7f90c929 100644 --- a/_overviews/collections/views.md +++ b/_overviews/collections/views.md @@ -5,7 +5,7 @@ title: Views discourse: true partof: collections -overview-name: Collections +overview-name: Collections (Scala 2.8 - 2.12) num: 14 From 06213510180fc9c12d9163d5498127095ceb5195 Mon Sep 17 00:00:00 2001 From: exoego Date: Mon, 22 Jul 2019 13:45:23 +0900 Subject: [PATCH 0623/3075] Add a link to newer version of collections. --- _overviews/collections/arrays.md | 5 +++++ .../collections/concrete-immutable-collection-classes.md | 5 +++++ .../collections/concrete-mutable-collection-classes.md | 5 +++++ .../conversions-between-java-and-scala-collections.md | 5 +++++ _overviews/collections/creating-collections-from-scratch.md | 5 +++++ _overviews/collections/equality.md | 5 +++++ _overviews/collections/introduction.md | 5 +++++ _overviews/collections/iterators.md | 5 +++++ _overviews/collections/maps.md | 5 +++++ _overviews/collections/migrating-from-scala-27.md | 5 +++++ _overviews/collections/overview.md | 5 +++++ _overviews/collections/performance-characteristics.md | 5 +++++ _overviews/collections/seqs.md | 5 +++++ _overviews/collections/sets.md | 5 +++++ _overviews/collections/strings.md | 5 +++++ _overviews/collections/trait-iterable.md | 5 +++++ _overviews/collections/trait-traversable.md | 5 +++++ _overviews/collections/views.md | 6 ++++++ _sass/layout/documentation.scss | 5 +++++ 19 files changed, 96 insertions(+) diff --git a/_overviews/collections/arrays.md b/_overviews/collections/arrays.md index bce565ea14..382af6a839 100644 --- a/_overviews/collections/arrays.md +++ b/_overviews/collections/arrays.md @@ -13,6 +13,11 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + [Array](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/Array.html) is a special kind of collection in Scala. On the one hand, Scala arrays correspond one-to-one to Java arrays. That is, a Scala array `Array[Int]` is represented as a Java `int[]`, an `Array[Double]` is represented as a Java `double[]` and a `Array[String]` is represented as a Java `String[]`. But at the same time, Scala arrays offer much more than their Java analogues. First, Scala arrays can be _generic_. That is, you can have an `Array[T]`, where `T` is a type parameter or abstract type. Second, Scala arrays are compatible with Scala sequences - you can pass an `Array[T]` where a `Seq[T]` is required. Finally, Scala arrays also support all sequence operations. Here's an example of this in action: scala> val a1 = Array(1, 2, 3) diff --git a/_overviews/collections/concrete-immutable-collection-classes.md b/_overviews/collections/concrete-immutable-collection-classes.md index 3f1fad4378..8e7e74d6f8 100644 --- a/_overviews/collections/concrete-immutable-collection-classes.md +++ b/_overviews/collections/concrete-immutable-collection-classes.md @@ -13,6 +13,11 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + Scala provides many concrete immutable collection classes for you to choose from. They differ in the traits they implement (maps, sets, sequences), whether they can be infinite, and the speed of various operations. Here are some of the most common immutable collection types used in Scala. ## Lists diff --git a/_overviews/collections/concrete-mutable-collection-classes.md b/_overviews/collections/concrete-mutable-collection-classes.md index 2e7e94e988..404a1715ee 100644 --- a/_overviews/collections/concrete-mutable-collection-classes.md +++ b/_overviews/collections/concrete-mutable-collection-classes.md @@ -13,6 +13,11 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + You've now seen the most commonly used immutable collection classes that Scala provides in its standard library. Take a look now at the mutable collection classes. ## Array Buffers diff --git a/_overviews/collections/conversions-between-java-and-scala-collections.md b/_overviews/collections/conversions-between-java-and-scala-collections.md index 7c7323125c..cb9675fae0 100644 --- a/_overviews/collections/conversions-between-java-and-scala-collections.md +++ b/_overviews/collections/conversions-between-java-and-scala-collections.md @@ -13,6 +13,11 @@ languages: [zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + Like Scala, Java also has a rich collections library. There are many similarities between the two. For instance, both libraries know iterators, iterables, sets, maps, and sequences. But there are also important differences. In particular, the Scala libraries put much more emphasis on immutable collections, and provide many more operations that transform a collection into a new one. Sometimes you might need to pass from one collection framework to the other. For instance, you might want to access an existing Java collection as if it were a Scala collection. Or you might want to pass one of Scala's collections to a Java method that expects its Java counterpart. It is quite easy to do this, because Scala offers implicit conversions between all the major collection types in the [JavaConverters](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/JavaConverters$.html) object. In particular, you will find bidirectional conversions between the following types. diff --git a/_overviews/collections/creating-collections-from-scratch.md b/_overviews/collections/creating-collections-from-scratch.md index d21c13d710..22c07d2016 100644 --- a/_overviews/collections/creating-collections-from-scratch.md +++ b/_overviews/collections/creating-collections-from-scratch.md @@ -13,6 +13,11 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + You have syntax `List(1, 2, 3)` to create a list of three integers and `Map('A' -> 1, 'C' -> 2)` to create a map with two bindings. This is actually a universal feature of Scala collections. You can take any collection name and follow it by a list of elements in parentheses. The result will be a new collection with the given elements. Here are some more examples: Traversable() // An empty traversable object diff --git a/_overviews/collections/equality.md b/_overviews/collections/equality.md index 08a8d110eb..1bded6008e 100644 --- a/_overviews/collections/equality.md +++ b/_overviews/collections/equality.md @@ -13,6 +13,11 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + The collection libraries have a uniform approach to equality and hashing. The idea is, first, to divide collections into sets, maps, and sequences. Collections in different categories are always unequal. For instance, `Set(1, 2, 3)` is unequal to `List(1, 2, 3)` even though they contain the same elements. On the other hand, within the same category, collections are equal if and only if they have the same elements (for sequences: the same elements in the same order). For example, `List(1, 2, 3) == Vector(1, 2, 3)`, and `HashSet(1, 2) == TreeSet(2, 1)`. It does not matter for the equality check whether a collection is mutable or immutable. For a mutable collection one simply considers its current elements at the time the equality test is performed. This means that a mutable collection might be equal to different collections at different times, depending what elements are added or removed. This is a potential trap when using a mutable collection as a key in a hashmap. Example: diff --git a/_overviews/collections/introduction.md b/_overviews/collections/introduction.md index c480affa85..23136be5ec 100644 --- a/_overviews/collections/introduction.md +++ b/_overviews/collections/introduction.md @@ -13,6 +13,11 @@ languages: [ja, zh-cn, ru] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + **Martin Odersky, and Lex Spoon** In the eyes of many, the new collections framework is the most significant diff --git a/_overviews/collections/iterators.md b/_overviews/collections/iterators.md index 02a41f1ed0..c273f87c12 100644 --- a/_overviews/collections/iterators.md +++ b/_overviews/collections/iterators.md @@ -13,6 +13,11 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + An iterator is not a collection, but rather a way to access the elements of a collection one by one. The two basic operations on an iterator `it` are `next` and `hasNext`. A call to `it.next()` will return the next element of the iterator and advance the state of the iterator. Calling `next` again on the same iterator will then yield the element one beyond the one returned previously. If there are no more elements to return, a call to `next` will throw a `NoSuchElementException`. You can find out whether there are more elements to return using [Iterator](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterator.html)'s `hasNext` method. The most straightforward way to "step through" all the elements returned by an iterator `it` uses a while-loop: diff --git a/_overviews/collections/maps.md b/_overviews/collections/maps.md index d7291dc6cb..6ba3b480b4 100644 --- a/_overviews/collections/maps.md +++ b/_overviews/collections/maps.md @@ -13,6 +13,11 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + A [Map](http://www.scala-lang.org/api/current/scala/collection/Map.html) is an [Iterable](http://www.scala-lang.org/api/current/scala/collection/Iterable.html) consisting of pairs of keys and values (also named _mappings_ or _associations_). Scala's [Predef](http://www.scala-lang.org/api/current/scala/Predef$.html) object offers an implicit conversion that lets you write `key -> value` as an alternate syntax for the pair `(key, value)`. For instance `Map("x" -> 24, "y" -> 25, "z" -> 26)` means exactly the same as `Map(("x", 24), ("y", 25), ("z", 26))`, but reads better. The fundamental operations on maps are similar to those on sets. They are summarized in the following table and fall into the following categories: diff --git a/_overviews/collections/migrating-from-scala-27.md b/_overviews/collections/migrating-from-scala-27.md index 939ef0987c..56760c67f9 100644 --- a/_overviews/collections/migrating-from-scala-27.md +++ b/_overviews/collections/migrating-from-scala-27.md @@ -13,6 +13,11 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + Porting your existing Scala applications to use the new collections should be almost automatic. There are only a couple of possible issues to take care of. Generally, the old functionality of Scala 2.7 collections has been left in place. Some features have been deprecated, which means they will removed in some future release. You will get a _deprecation warning_ when you compile code that makes use of these features in Scala 2.8. In a few places deprecation was unfeasible, because the operation in question was retained in 2.8, but changed in meaning or performance characteristics. These cases will be flagged with _migration warnings_ when compiled under 2.8. To get full deprecation and migration warnings with suggestions how to change your code, pass the `-deprecation` and `-Xmigration` flags to `scalac` (note that `-Xmigration` is an extended option, so it starts with an `X`). You can also pass the same options to the `scala` REPL to get the warnings in an interactive session. Example: diff --git a/_overviews/collections/overview.md b/_overviews/collections/overview.md index b4c73e0567..cc46a849ba 100644 --- a/_overviews/collections/overview.md +++ b/_overviews/collections/overview.md @@ -13,6 +13,11 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + Scala collections systematically distinguish between mutable and immutable collections. A _mutable_ collection can be updated or extended in place. This means you can change, add, or remove elements diff --git a/_overviews/collections/performance-characteristics.md b/_overviews/collections/performance-characteristics.md index e6e1e92537..96cbacbe59 100644 --- a/_overviews/collections/performance-characteristics.md +++ b/_overviews/collections/performance-characteristics.md @@ -13,6 +13,11 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + The previous explanations have made it clear that different collection types have different performance characteristics. That's often the primary reason for picking one collection type over another. You can see the performance characteristics of some common operations on collections summarized in the following two tables. Performance characteristics of sequence types: diff --git a/_overviews/collections/seqs.md b/_overviews/collections/seqs.md index a932a8ce4b..17aa7f708b 100644 --- a/_overviews/collections/seqs.md +++ b/_overviews/collections/seqs.md @@ -13,6 +13,11 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + The [Seq](http://www.scala-lang.org/api/current/scala/collection/Seq.html) trait represents sequences. A sequence is a kind of iterable that has a `length` and whose elements have fixed index positions, starting from `0`. The operations on sequences, summarized in the table below, fall into the following categories: diff --git a/_overviews/collections/sets.md b/_overviews/collections/sets.md index d93a03acad..85d21f3c28 100644 --- a/_overviews/collections/sets.md +++ b/_overviews/collections/sets.md @@ -13,6 +13,11 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + `Set`s are `Iterable`s that contain no duplicate elements. The operations on sets are summarized in the following table for general sets and in the table after that for mutable sets. They fall into the following categories: * **Tests** `contains`, `apply`, `subsetOf`. The `contains` method asks whether a set contains a given element. The `apply` method for a set is the same as `contains`, so `set(elem)` is the same as `set contains elem`. That means sets can also be used as test functions that return true for the elements they contain. diff --git a/_overviews/collections/strings.md b/_overviews/collections/strings.md index 058fb8b281..a6545dbf6a 100644 --- a/_overviews/collections/strings.md +++ b/_overviews/collections/strings.md @@ -13,6 +13,11 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + Like arrays, strings are not directly sequences, but they can be converted to them, and they also support all sequence operations on strings. Here are some examples of operations you can invoke on strings. scala> val str = "hello" diff --git a/_overviews/collections/trait-iterable.md b/_overviews/collections/trait-iterable.md index f8f0bf7763..b708c251f5 100644 --- a/_overviews/collections/trait-iterable.md +++ b/_overviews/collections/trait-iterable.md @@ -13,6 +13,11 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + The next trait from the top in the collections hierarchy is `Iterable`. All methods in this trait are defined in terms of an abstract method, `iterator`, which yields the collection's elements one by one. The `foreach` method from trait `Traversable` is implemented in `Iterable` in terms of `iterator`. Here is the actual implementation: def foreach[U](f: Elem => U): Unit = { diff --git a/_overviews/collections/trait-traversable.md b/_overviews/collections/trait-traversable.md index a954246f99..010a74fedb 100644 --- a/_overviews/collections/trait-traversable.md +++ b/_overviews/collections/trait-traversable.md @@ -13,6 +13,11 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + At the top of the collection hierarchy is trait `Traversable`. Its only abstract operation is `foreach`: def foreach[U](f: Elem => U) diff --git a/_overviews/collections/views.md b/_overviews/collections/views.md index 2a7f90c929..4968547708 100644 --- a/_overviews/collections/views.md +++ b/_overviews/collections/views.md @@ -13,6 +13,12 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- + + See this in Scala 2.13 + + + Collections have quite a few methods that construct new collections. Examples are `map`, `filter` or `++`. We call such methods transformers because they take at least one collection as their receiver object and produce another collection as their result. There are two principal ways to implement transformers. One is _strict_, that is a new collection with all its elements is constructed as a result of the transformer. The other is non-strict or _lazy_, that is one constructs only a proxy for the result collection, and its elements get constructed only as one demands them. diff --git a/_sass/layout/documentation.scss b/_sass/layout/documentation.scss index 9a04495b27..c9c121e9a6 100644 --- a/_sass/layout/documentation.scss +++ b/_sass/layout/documentation.scss @@ -57,3 +57,8 @@ padding: 1px 5px; } } + +.link-to-newer-version { + float: right; + padding: 0 0 1em 1em; +} From a22c2b648225d06cbb394f38348b4b65d5ac4d34 Mon Sep 17 00:00:00 2001 From: exoego Date: Mon, 22 Jul 2019 14:21:32 +0900 Subject: [PATCH 0624/3075] There is no newer version for those 2 pages. --- _overviews/collections/migrating-from-scala-27.md | 5 ----- _overviews/collections/trait-traversable.md | 5 ----- 2 files changed, 10 deletions(-) diff --git a/_overviews/collections/migrating-from-scala-27.md b/_overviews/collections/migrating-from-scala-27.md index 56760c67f9..939ef0987c 100644 --- a/_overviews/collections/migrating-from-scala-27.md +++ b/_overviews/collections/migrating-from-scala-27.md @@ -13,11 +13,6 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - Porting your existing Scala applications to use the new collections should be almost automatic. There are only a couple of possible issues to take care of. Generally, the old functionality of Scala 2.7 collections has been left in place. Some features have been deprecated, which means they will removed in some future release. You will get a _deprecation warning_ when you compile code that makes use of these features in Scala 2.8. In a few places deprecation was unfeasible, because the operation in question was retained in 2.8, but changed in meaning or performance characteristics. These cases will be flagged with _migration warnings_ when compiled under 2.8. To get full deprecation and migration warnings with suggestions how to change your code, pass the `-deprecation` and `-Xmigration` flags to `scalac` (note that `-Xmigration` is an extended option, so it starts with an `X`). You can also pass the same options to the `scala` REPL to get the warnings in an interactive session. Example: diff --git a/_overviews/collections/trait-traversable.md b/_overviews/collections/trait-traversable.md index 010a74fedb..a954246f99 100644 --- a/_overviews/collections/trait-traversable.md +++ b/_overviews/collections/trait-traversable.md @@ -13,11 +13,6 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - At the top of the collection hierarchy is trait `Traversable`. Its only abstract operation is `foreach`: def foreach[U](f: Elem => U) From 843382f1f35a79250803d704612226cbb2a5f467 Mon Sep 17 00:00:00 2001 From: exoego Date: Tue, 23 Jul 2019 12:13:52 +0900 Subject: [PATCH 0625/3075] Add newer version notice --- _layouts/inner-page-parent-dropdown.html | 1 + _layouts/inner-page-parent.html | 4 ++-- _overviews/collections/arrays.md | 6 +----- .../collections/concrete-immutable-collection-classes.md | 6 +----- .../collections/concrete-mutable-collection-classes.md | 6 +----- .../conversions-between-java-and-scala-collections.md | 6 +----- .../collections/creating-collections-from-scratch.md | 6 +----- _overviews/collections/equality.md | 6 +----- _overviews/collections/introduction.md | 6 +----- _overviews/collections/iterators.md | 6 +----- _overviews/collections/maps.md | 6 +----- _overviews/collections/overview.md | 6 +----- _overviews/collections/performance-characteristics.md | 6 +----- _overviews/collections/seqs.md | 6 +----- _overviews/collections/sets.md | 6 +----- _overviews/collections/strings.md | 6 +----- _overviews/collections/trait-iterable.md | 6 +----- _overviews/collections/views.md | 7 +------ _sass/layout/documentation.scss | 8 +++++--- 19 files changed, 24 insertions(+), 86 deletions(-) diff --git a/_layouts/inner-page-parent-dropdown.html b/_layouts/inner-page-parent-dropdown.html index d2e5029f68..5b89d3ef47 100644 --- a/_layouts/inner-page-parent-dropdown.html +++ b/_layouts/inner-page-parent-dropdown.html @@ -1,5 +1,6 @@ {% include headertop.html %} {% include headerbottom.html %} +{% if page.new-version %}This page has a new version.{% endif %} diff --git a/_layouts/inner-page-parent.html b/_layouts/inner-page-parent.html index 3ed25753ca..2dc28bb539 100644 --- a/_layouts/inner-page-parent.html +++ b/_layouts/inner-page-parent.html @@ -1,4 +1,5 @@ {% include headertop.html %} {% include headerbottom.html %} + {% if page.new-version %}This page has a new version.{% endif %} @@ -20,7 +21,6 @@

{{page.title}}

-
@@ -28,4 +28,4 @@

{{page.title}}

-{% include footer.html %} \ No newline at end of file +{% include footer.html %} diff --git a/_overviews/collections/arrays.md b/_overviews/collections/arrays.md index 382af6a839..74af34c41a 100644 --- a/_overviews/collections/arrays.md +++ b/_overviews/collections/arrays.md @@ -6,6 +6,7 @@ discourse: true partof: collections overview-name: Collections (Scala 2.8 - 2.12) +new-version: /overviews/collections-2.13/arrays.html num: 10 @@ -13,11 +14,6 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - [Array](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/Array.html) is a special kind of collection in Scala. On the one hand, Scala arrays correspond one-to-one to Java arrays. That is, a Scala array `Array[Int]` is represented as a Java `int[]`, an `Array[Double]` is represented as a Java `double[]` and a `Array[String]` is represented as a Java `String[]`. But at the same time, Scala arrays offer much more than their Java analogues. First, Scala arrays can be _generic_. That is, you can have an `Array[T]`, where `T` is a type parameter or abstract type. Second, Scala arrays are compatible with Scala sequences - you can pass an `Array[T]` where a `Seq[T]` is required. Finally, Scala arrays also support all sequence operations. Here's an example of this in action: scala> val a1 = Array(1, 2, 3) diff --git a/_overviews/collections/concrete-immutable-collection-classes.md b/_overviews/collections/concrete-immutable-collection-classes.md index 8e7e74d6f8..f18caed726 100644 --- a/_overviews/collections/concrete-immutable-collection-classes.md +++ b/_overviews/collections/concrete-immutable-collection-classes.md @@ -6,6 +6,7 @@ discourse: true partof: collections overview-name: Collections (Scala 2.8 - 2.12) +new-version: /overviews/collections-2.13/concrete-immutable-collection-classes.html num: 8 @@ -13,11 +14,6 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - Scala provides many concrete immutable collection classes for you to choose from. They differ in the traits they implement (maps, sets, sequences), whether they can be infinite, and the speed of various operations. Here are some of the most common immutable collection types used in Scala. ## Lists diff --git a/_overviews/collections/concrete-mutable-collection-classes.md b/_overviews/collections/concrete-mutable-collection-classes.md index 404a1715ee..c54343554d 100644 --- a/_overviews/collections/concrete-mutable-collection-classes.md +++ b/_overviews/collections/concrete-mutable-collection-classes.md @@ -6,6 +6,7 @@ discourse: true partof: collections overview-name: Collections (Scala 2.8 - 2.12) +new-version: /overviews/collections-2.13/concrete-mutable-collection-classes.html num: 9 @@ -13,11 +14,6 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - You've now seen the most commonly used immutable collection classes that Scala provides in its standard library. Take a look now at the mutable collection classes. ## Array Buffers diff --git a/_overviews/collections/conversions-between-java-and-scala-collections.md b/_overviews/collections/conversions-between-java-and-scala-collections.md index cb9675fae0..290726fdab 100644 --- a/_overviews/collections/conversions-between-java-and-scala-collections.md +++ b/_overviews/collections/conversions-between-java-and-scala-collections.md @@ -6,6 +6,7 @@ discourse: true partof: collections overview-name: Collections (Scala 2.8 - 2.12) +new-version: /overviews/collections-2.13/conversions-between-java-and-scala-collections.html num: 17 @@ -13,11 +14,6 @@ languages: [zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - Like Scala, Java also has a rich collections library. There are many similarities between the two. For instance, both libraries know iterators, iterables, sets, maps, and sequences. But there are also important differences. In particular, the Scala libraries put much more emphasis on immutable collections, and provide many more operations that transform a collection into a new one. Sometimes you might need to pass from one collection framework to the other. For instance, you might want to access an existing Java collection as if it were a Scala collection. Or you might want to pass one of Scala's collections to a Java method that expects its Java counterpart. It is quite easy to do this, because Scala offers implicit conversions between all the major collection types in the [JavaConverters](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/JavaConverters$.html) object. In particular, you will find bidirectional conversions between the following types. diff --git a/_overviews/collections/creating-collections-from-scratch.md b/_overviews/collections/creating-collections-from-scratch.md index 22c07d2016..1732a844e6 100644 --- a/_overviews/collections/creating-collections-from-scratch.md +++ b/_overviews/collections/creating-collections-from-scratch.md @@ -6,6 +6,7 @@ discourse: true partof: collections overview-name: Collections (Scala 2.8 - 2.12) +new-version: /overviews/collections-2.13/creating-collections-from-scratch.html num: 16 @@ -13,11 +14,6 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - You have syntax `List(1, 2, 3)` to create a list of three integers and `Map('A' -> 1, 'C' -> 2)` to create a map with two bindings. This is actually a universal feature of Scala collections. You can take any collection name and follow it by a list of elements in parentheses. The result will be a new collection with the given elements. Here are some more examples: Traversable() // An empty traversable object diff --git a/_overviews/collections/equality.md b/_overviews/collections/equality.md index 1bded6008e..e368d64b35 100644 --- a/_overviews/collections/equality.md +++ b/_overviews/collections/equality.md @@ -6,6 +6,7 @@ discourse: true partof: collections overview-name: Collections (Scala 2.8 - 2.12) +new-version: /overviews/collections-2.13/creating-collections-from-scratch.html num: 13 @@ -13,11 +14,6 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - The collection libraries have a uniform approach to equality and hashing. The idea is, first, to divide collections into sets, maps, and sequences. Collections in different categories are always unequal. For instance, `Set(1, 2, 3)` is unequal to `List(1, 2, 3)` even though they contain the same elements. On the other hand, within the same category, collections are equal if and only if they have the same elements (for sequences: the same elements in the same order). For example, `List(1, 2, 3) == Vector(1, 2, 3)`, and `HashSet(1, 2) == TreeSet(2, 1)`. It does not matter for the equality check whether a collection is mutable or immutable. For a mutable collection one simply considers its current elements at the time the equality test is performed. This means that a mutable collection might be equal to different collections at different times, depending what elements are added or removed. This is a potential trap when using a mutable collection as a key in a hashmap. Example: diff --git a/_overviews/collections/introduction.md b/_overviews/collections/introduction.md index 23136be5ec..39445c561f 100644 --- a/_overviews/collections/introduction.md +++ b/_overviews/collections/introduction.md @@ -6,6 +6,7 @@ discourse: true partof: collections overview-name: Collections (Scala 2.8 - 2.12) +new-version: /overviews/collections-2.13/introduction.html num: 1 @@ -13,11 +14,6 @@ languages: [ja, zh-cn, ru] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - **Martin Odersky, and Lex Spoon** In the eyes of many, the new collections framework is the most significant diff --git a/_overviews/collections/iterators.md b/_overviews/collections/iterators.md index c273f87c12..abb3ca4a97 100644 --- a/_overviews/collections/iterators.md +++ b/_overviews/collections/iterators.md @@ -6,6 +6,7 @@ discourse: true partof: collections overview-name: Collections (Scala 2.8 - 2.12) +new-version: /overviews/collections-2.13/iterators.html num: 15 @@ -13,11 +14,6 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - An iterator is not a collection, but rather a way to access the elements of a collection one by one. The two basic operations on an iterator `it` are `next` and `hasNext`. A call to `it.next()` will return the next element of the iterator and advance the state of the iterator. Calling `next` again on the same iterator will then yield the element one beyond the one returned previously. If there are no more elements to return, a call to `next` will throw a `NoSuchElementException`. You can find out whether there are more elements to return using [Iterator](http://www.scala-lang.org/api/{{ site.scala-212-version }}/scala/collection/Iterator.html)'s `hasNext` method. The most straightforward way to "step through" all the elements returned by an iterator `it` uses a while-loop: diff --git a/_overviews/collections/maps.md b/_overviews/collections/maps.md index 6ba3b480b4..93b73342fa 100644 --- a/_overviews/collections/maps.md +++ b/_overviews/collections/maps.md @@ -6,6 +6,7 @@ discourse: true partof: collections overview-name: Collections (Scala 2.8 - 2.12) +new-version: /overviews/collections-2.13/maps.html num: 7 @@ -13,11 +14,6 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - A [Map](http://www.scala-lang.org/api/current/scala/collection/Map.html) is an [Iterable](http://www.scala-lang.org/api/current/scala/collection/Iterable.html) consisting of pairs of keys and values (also named _mappings_ or _associations_). Scala's [Predef](http://www.scala-lang.org/api/current/scala/Predef$.html) object offers an implicit conversion that lets you write `key -> value` as an alternate syntax for the pair `(key, value)`. For instance `Map("x" -> 24, "y" -> 25, "z" -> 26)` means exactly the same as `Map(("x", 24), ("y", 25), ("z", 26))`, but reads better. The fundamental operations on maps are similar to those on sets. They are summarized in the following table and fall into the following categories: diff --git a/_overviews/collections/overview.md b/_overviews/collections/overview.md index cc46a849ba..2b3db7713b 100644 --- a/_overviews/collections/overview.md +++ b/_overviews/collections/overview.md @@ -6,6 +6,7 @@ discourse: true partof: collections overview-name: Collections (Scala 2.8 - 2.12) +new-version: /overviews/collections-2.13/overview.html num: 2 @@ -13,11 +14,6 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - Scala collections systematically distinguish between mutable and immutable collections. A _mutable_ collection can be updated or extended in place. This means you can change, add, or remove elements diff --git a/_overviews/collections/performance-characteristics.md b/_overviews/collections/performance-characteristics.md index 96cbacbe59..55e8080163 100644 --- a/_overviews/collections/performance-characteristics.md +++ b/_overviews/collections/performance-characteristics.md @@ -6,6 +6,7 @@ discourse: true partof: collections overview-name: Collections (Scala 2.8 - 2.12) +new-version: /overviews/collections-2.13/performance-characteristics.html num: 12 @@ -13,11 +14,6 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - The previous explanations have made it clear that different collection types have different performance characteristics. That's often the primary reason for picking one collection type over another. You can see the performance characteristics of some common operations on collections summarized in the following two tables. Performance characteristics of sequence types: diff --git a/_overviews/collections/seqs.md b/_overviews/collections/seqs.md index 17aa7f708b..9883ce9c36 100644 --- a/_overviews/collections/seqs.md +++ b/_overviews/collections/seqs.md @@ -6,6 +6,7 @@ discourse: true partof: collections overview-name: Collections (Scala 2.8 - 2.12) +new-version: /overviews/collections-2.13/seqs.html num: 5 @@ -13,11 +14,6 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - The [Seq](http://www.scala-lang.org/api/current/scala/collection/Seq.html) trait represents sequences. A sequence is a kind of iterable that has a `length` and whose elements have fixed index positions, starting from `0`. The operations on sequences, summarized in the table below, fall into the following categories: diff --git a/_overviews/collections/sets.md b/_overviews/collections/sets.md index 85d21f3c28..76745eb8bb 100644 --- a/_overviews/collections/sets.md +++ b/_overviews/collections/sets.md @@ -6,6 +6,7 @@ discourse: true partof: collections overview-name: Collections (Scala 2.8 - 2.12) +new-version: /overviews/collections-2.13/sets.html num: 6 @@ -13,11 +14,6 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - `Set`s are `Iterable`s that contain no duplicate elements. The operations on sets are summarized in the following table for general sets and in the table after that for mutable sets. They fall into the following categories: * **Tests** `contains`, `apply`, `subsetOf`. The `contains` method asks whether a set contains a given element. The `apply` method for a set is the same as `contains`, so `set(elem)` is the same as `set contains elem`. That means sets can also be used as test functions that return true for the elements they contain. diff --git a/_overviews/collections/strings.md b/_overviews/collections/strings.md index a6545dbf6a..bb1a66dd5f 100644 --- a/_overviews/collections/strings.md +++ b/_overviews/collections/strings.md @@ -6,6 +6,7 @@ discourse: true partof: collections overview-name: Collections (Scala 2.8 - 2.12) +new-version: /overviews/collections-2.13/strings.html num: 11 @@ -13,11 +14,6 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - Like arrays, strings are not directly sequences, but they can be converted to them, and they also support all sequence operations on strings. Here are some examples of operations you can invoke on strings. scala> val str = "hello" diff --git a/_overviews/collections/trait-iterable.md b/_overviews/collections/trait-iterable.md index b708c251f5..5f07a242c8 100644 --- a/_overviews/collections/trait-iterable.md +++ b/_overviews/collections/trait-iterable.md @@ -6,6 +6,7 @@ discourse: true partof: collections overview-name: Collections (Scala 2.8 - 2.12) +new-version: /overviews/collections-2.13/trait-iterable.html num: 4 @@ -13,11 +14,6 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - The next trait from the top in the collections hierarchy is `Iterable`. All methods in this trait are defined in terms of an abstract method, `iterator`, which yields the collection's elements one by one. The `foreach` method from trait `Traversable` is implemented in `Iterable` in terms of `iterator`. Here is the actual implementation: def foreach[U](f: Elem => U): Unit = { diff --git a/_overviews/collections/views.md b/_overviews/collections/views.md index 4968547708..86bacf29e1 100644 --- a/_overviews/collections/views.md +++ b/_overviews/collections/views.md @@ -6,6 +6,7 @@ discourse: true partof: collections overview-name: Collections (Scala 2.8 - 2.12) +new-version: /overviews/collections-2.13/views.html num: 14 @@ -13,12 +14,6 @@ languages: [ja, zh-cn] permalink: /overviews/collections/:title.html --- - - See this in Scala 2.13 - - - Collections have quite a few methods that construct new collections. Examples are `map`, `filter` or `++`. We call such methods transformers because they take at least one collection as their receiver object and produce another collection as their result. There are two principal ways to implement transformers. One is _strict_, that is a new collection with all its elements is constructed as a result of the transformer. The other is non-strict or _lazy_, that is one constructs only a proxy for the result collection, and its elements get constructed only as one demands them. diff --git a/_sass/layout/documentation.scss b/_sass/layout/documentation.scss index c9c121e9a6..f1a16f69d5 100644 --- a/_sass/layout/documentation.scss +++ b/_sass/layout/documentation.scss @@ -58,7 +58,9 @@ } } -.link-to-newer-version { - float: right; - padding: 0 0 1em 1em; +a.new-version-notice { + display: block; + background: rgb(255, 255, 200); + font-size: large; + text-align: center; } From 26e40b026b8cdb98abb560d1a7334d71332d6dda Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Tue, 23 Jul 2019 14:07:12 -0700 Subject: [PATCH 0626/3075] update spec version in footer fixes #1447 --- _data/footer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_data/footer.yml b/_data/footer.yml index 04e60f45eb..b810181f92 100644 --- a/_data/footer.yml +++ b/_data/footer.yml @@ -8,7 +8,7 @@ - title: Overviews/Guides url: "/overviews" - title: Language Specification - url: "http://scala-lang.org/files/archive/spec/2.12/" + url: "http://scala-lang.org/files/archive/spec/2.13/" - title: Download class: download links: From cac3f800cf5654c4d6a00f107c7b7c7cd5729937 Mon Sep 17 00:00:00 2001 From: exoego Date: Wed, 24 Jul 2019 08:14:40 +0900 Subject: [PATCH 0627/3075] Move cheatsheet to its own collection just like site structure. --- {_overviews/cheatsheets => _cheatsheets}/index.md | 1 - _config.yml | 3 +++ _layouts/cheatsheet.html | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) rename {_overviews/cheatsheets => _cheatsheets}/index.md (99%) diff --git a/_overviews/cheatsheets/index.md b/_cheatsheets/index.md similarity index 99% rename from _overviews/cheatsheets/index.md rename to _cheatsheets/index.md index 07d96b55c8..67d4c59144 100644 --- a/_overviews/cheatsheets/index.md +++ b/_cheatsheets/index.md @@ -8,7 +8,6 @@ by: Brendan O'Connor about: Thanks to Brendan O'Connor, this cheatsheet aims to be a quick reference of Scala syntactic constructions. Licensed by Brendan O'Connor under a CC-BY-SA 3.0 license. languages: [ba, fr, ja, pl, pt-br, zh-cn, th, ru] -permalink: /cheatsheets/index.html --- diff --git a/_config.yml b/_config.yml index 320c7a9839..2862096ac9 100644 --- a/_config.yml +++ b/_config.yml @@ -35,6 +35,9 @@ collections: sips: output: true permalink: /:collection/:path.html + cheatsheets: + output: true + permalink: /:collection/:path.html books: output: false ja: # Japanese translations diff --git a/_layouts/cheatsheet.html b/_layouts/cheatsheet.html index 9e0e978e63..9ee9695c01 100644 --- a/_layouts/cheatsheet.html +++ b/_layouts/cheatsheet.html @@ -22,7 +22,7 @@ {% elsif page.language %} {% assign engPath = page.id | remove_first: "/" | remove_first: page.language | append: '.html' %} - {% assign engPg = site.overviews | where: 'partof', page.partof | first %} + {% assign engPg = site.cheatsheets | where: 'partof', page.partof | first %} {{ engPg.languages }} - + diff --git a/_overviews/contributors/index.md b/_overviews/contributors/index.md index 0d31996273..c20879ffbd 100644 --- a/_overviews/contributors/index.md +++ b/_overviews/contributors/index.md @@ -742,7 +742,7 @@ Last, add the following job to the “test” stage, in the `.travis.yml` file: This will check that pull requests don’t make changes that are binary incompatible with the previous stable version. -We suggest working with the following Git workflow: the `master` branch always receives pull requests +We suggest working with the following Git workflow: the `main` branch always receives pull requests for the next major version (so, binary compatibility checks are disabled, by setting the `mimaPreviousArtifacts` value to `Set.empty`), and each major version `N` has a corresponding `N.x` branch (e.g., `1.x`, `2.x`, etc.) branch where the binary compatibility checks are enabled. diff --git a/_sips/sip-submission.md b/_sips/sip-submission.md index 1d7d1d0609..e2efb5ec2a 100644 --- a/_sips/sip-submission.md +++ b/_sips/sip-submission.md @@ -76,7 +76,7 @@ a SIP or needs more work. After receiving the green light from the Process Lead, you can write up your idea and submit it as a SIP. -A SIP is a Markdown document written in conformance with the [process template](https://github.com/scala/docs.scala-lang/blob/master/_sips/sip-template.md). +A SIP is a Markdown document written in conformance with the [process template](https://github.com/scala/docs.scala-lang/blob/main/_sips/sip-template.md). It ought to contain a clear specification of the proposed changes. When such changes significantly alter the compiler internals, the author is invited to provide a proof of concept. Delivering a basic implementation can speed up the @@ -323,7 +323,7 @@ Scala compiler. The process to submit is simple: * Fork the Scala documentation repository, [https://github.com/scala/docs.scala-lang](https://github.com/scala/docs.scala-lang). -* Create a new SIP file in the `_sips/sips/`. Use the [S(L)IP template](https://github.com/scala/docs.scala-lang/blob/master/_sips/sip-template.md) +* Create a new SIP file in the `_sips/sips/`. Use the [S(L)IP template](https://github.com/scala/docs.scala-lang/blob/main/_sips/sip-template.md) * Make sure the new file follows the format: `YYYY-MM-dd-{title}.md`. Use the proposal date for `YYYY-MM-dd`. * Use the [Markdown Syntax](https://daringfireball.net/projects/markdown/syntax) to write your SIP. * Follow the instructions in the [README](https://github.com/scala/docs.scala-lang/) to build your SIP locally so you can ensure that it looks correct on the website. diff --git a/_sips/sip-tutorial.md b/_sips/sip-tutorial.md index 2696fd12af..6103c16d94 100644 --- a/_sips/sip-tutorial.md +++ b/_sips/sip-tutorial.md @@ -10,10 +10,10 @@ This tutorial details of how to write a new SIP and adding it to the website. The process to submit is simple: * Fork the [Scala documentation repository](https://github.com/scala/docs.scala-lang) and clone it. -* Create a new SIP file in the `_sips/sips`. Use the [SIP template](https://github.com/scala/docs.scala-lang/blob/master/_sips/sip-template.md) +* Create a new SIP file in the `_sips/sips`. Use the [SIP template](https://github.com/scala/docs.scala-lang/blob/main/_sips/sip-template.md) * Make sure the new file follows the format: `YYYY-MM-dd-{title}.md`. Use the proposal date for `YYYY-MM-dd`. * Use the [Markdown Syntax](https://daringfireball.net/projects/markdown/syntax) to write your SIP. - * Follow the instructions in the [README](https://github.com/scala/docs.scala-lang/blob/master/README.md) to build your SIP locally so you can ensure that it looks correct on the website. + * Follow the instructions in the [README](https://github.com/scala/docs.scala-lang/blob/main/README.md) to build your SIP locally so you can ensure that it looks correct on the website. * Create a link to your SIP in the "pending sips" section of `index.md`. * Commit your changes and push them to your forked repository. * Create a new pull request. This will notify the Scala SIP team. @@ -34,7 +34,7 @@ Use the [Markdown Syntax](https://daringfireball.net/projects/markdown/syntax) t If you would like a starting point, clone the [SIP Template](./sip-template.html) in `_sips/sip-template.md` and use that. -See the [source](https://github.com/scala/docs.scala-lang/blob/master/_sips/sip-template.md) for this document (`sip-tutorial.md`) for how to do syntax highlighting. +See the [source](https://github.com/scala/docs.scala-lang/blob/main/_sips/sip-template.md) for this document (`sip-tutorial.md`) for how to do syntax highlighting. ```scala class Foo @@ -46,6 +46,6 @@ class Foo Testing changes requires installing [Jekyll](https://jekyllrb.com/docs/installation/). Since this site is hosted on github pages, make sure you have [whatever version of Jekyll that github is running](https://help.github.com/articles/using-jekyll-with-pages#troubleshooting). As of the writing of this README, that is version >= 1.0.x. After the installation, you need to start up the local server. The -[README](https://github.com/scala/docs.scala-lang/blob/master/README.md) gives +[README](https://github.com/scala/docs.scala-lang/blob/main/README.md) gives a concise explanation on how to do it. When the server is running, view your changes at [https://localhost:4000/sips](https://localhost:4000/sips). diff --git a/scala3/contribute-to-docs.md b/scala3/contribute-to-docs.md index 25d719a764..91b467766f 100644 --- a/scala3/contribute-to-docs.md +++ b/scala3/contribute-to-docs.md @@ -28,13 +28,13 @@ Typically, each of the different documentation projects contain links (and so do ## Scala 3 Book The [Scala 3 Book][scala3-book] is being written by Alvin Alexander and provides an overview over all the important features of Scala 3. It targets readers, which are new to Scala. -- [Sources](https://github.com/scala/docs.scala-lang/tree/master/_overviews/scala3-book) +- [Sources](https://github.com/scala/docs.scala-lang/tree/main/_overviews/scala3-book) - [Issues](https://github.com/scala/docs.scala-lang/issues) ## Macros Tutorial The [Macros Tutorial](/scala3/guides/macros) is being written by Nicolas Stucki and contains detailed information about macros in Scala 3 and best-practices. -- [Sources](https://github.com/scala/docs.scala-lang/tree/master/_overviews/scala3-macros) +- [Sources](https://github.com/scala/docs.scala-lang/tree/main/_overviews/scala3-macros) - [Issues](https://github.com/scala/docs.scala-lang/issues) ## Migration Guide @@ -42,7 +42,7 @@ The [Scala 3 Migration Guide](/scala3/guides/migration/compatibility-intro.html) contains an comprehensive overview over compatibility between Scala 2 and Scala 3, a tour presenting the migration tools, and detailed migration guides. -- [Source](https://github.com/scala/docs.scala-lang/tree/master/_overviews/scala3-migration) +- [Source](https://github.com/scala/docs.scala-lang/tree/main/_overviews/scala3-migration) - [Issues](https://github.com/scalacenter/docs.scala-lang/issues) ## Scala 3 Language Reference From 3d94c2fb4c6df2b8db2bfda9209c5bd65aab64c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Koz=C5=82owski?= Date: Wed, 2 Jun 2021 19:17:24 +0200 Subject: [PATCH 1491/3075] Update index.md --- _overviews/plugins/index.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/_overviews/plugins/index.md b/_overviews/plugins/index.md index 9e1b2015b7..20b3508cf9 100644 --- a/_overviews/plugins/index.md +++ b/_overviews/plugins/index.md @@ -46,11 +46,10 @@ include: - Plugins that alter Scala's behavior around errors and warnings, such as [silencer](https://github.com/ghik/silencer), [splain](https://github.com/tek/splain) and [clippy](https://scala-clippy.org/). - Plugins that analyze the structure of source code, such as - [Sculpt](https://github.com/lightbend/scala-sculpt) and [acyclic](https://github.com/lihaoyi/acyclic). + [Sculpt](https://github.com/lightbend/scala-sculpt), [acyclic](https://github.com/lihaoyi/acyclic) and [graph-buddy](https://github.com/VirtusLab/graphbuddy). - Plugins that instrument user code to collect information, such as the code coverage tool [scoverage](https://github.com/scoverage/scalac-scoverage-plugin). -- Plugins that add metaprogramming facilities to Scala, - such as [Macro Paradise](https://github.com/scalamacros/paradise), [semanticdb](https://scalameta.org/docs/semanticdb/guide.html). +- Plugins that enable tooling. One such plugin is [semanticdb](https://scalameta.org/docs/semanticdb/guide.html), which enables [scalafix](https://scalacenter.github.io/scalafix/) (a well-known refactoring and linting tool) to do its work. Another one is [Macro Paradise](https://github.com/scalamacros/paradise) (only needed for Scala 2.12). - Plugins that modify existing Scala constructs in user code, such as [better-monadic-for](https://github.com/oleg-py/better-monadic-for) and [better-tostring](https://github.com/polyvariant/better-tostring). - Plugins that add entirely new constructs to Scala by From 619652ef2d82107bdc03acfbb55877abd2fec84d Mon Sep 17 00:00:00 2001 From: nscarcella Date: Thu, 3 Jun 2021 03:37:26 -0300 Subject: [PATCH 1492/3075] Fixed typos (#2049) * Fixed missing `then` keyword * Replaced Any type for Matchable * Adding missing parenthesis * Added short Matchable description --- _overviews/scala3-book/fun-write-map-function.md | 4 ++-- _overviews/scala3-book/methods-most.md | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/_overviews/scala3-book/fun-write-map-function.md b/_overviews/scala3-book/fun-write-map-function.md index 37a0748074..633d9b8fb8 100644 --- a/_overviews/scala3-book/fun-write-map-function.md +++ b/_overviews/scala3-book/fun-write-map-function.md @@ -20,13 +20,13 @@ Given that statement, you start to write the method signature. First, you know that you want to accept a function as a parameter, and that function should transform an `Int` into some generic type `A`, so you write: ```scala -def map(f: (Int) => A +def map(f: (Int) => A) ``` The syntax for using a generic type requires declaring that type symbol before the parameter list, so you add that: ```scala -def map[A](f: (Int) => A +def map[A](f: (Int) => A) ``` Next, you know that `map` should also accept a `List[Int]`: diff --git a/_overviews/scala3-book/methods-most.md b/_overviews/scala3-book/methods-most.md index b501b1687b..ac2140a41b 100644 --- a/_overviews/scala3-book/methods-most.md +++ b/_overviews/scala3-book/methods-most.md @@ -233,7 +233,7 @@ Here’s a method named `isTruthy` that implements the Perl definitions of `true ```scala def isTruthy(a: Any) = - if a == 0 || a == "" + if a == 0 || a == "" then false else true @@ -256,13 +256,14 @@ A `match` expression can also be used as the entire method body, and often is. Here’s another version of `isTruthy`, written with a `match` expression : ```scala -def isTruthy(a: Any) = a match +def isTruthy(a: Matchable) = a match case 0 | "" => false case _ => true ``` -This method works just like the previous method that used an `if`/`else` expression. +This method works just like the previous method that used an `if`/`else` expression. We use `Matchable` instead of `Any` as the parameter's type to accept any value that supports pattern matching. +For more details on the `Matchable` trait, see the [Reference documentation][reference_matchable]. ## Controlling visibility in classes @@ -401,3 +402,4 @@ See the [Reference documentation][reference] for more details on these features. [extension]: {% link _overviews/scala3-book/ca-extension-methods.md %} [reference_extension_methods]: {{ site.scala3ref }}/contextual/extension-methods.html [reference]: {{ site.scala3ref }}/overview.html +[reference_matchable]: {{ site.scala3ref }}/other-new-features/matchable.html From 6b2ae553fc0b34e1b6f78b30a81e6892e59b3553 Mon Sep 17 00:00:00 2001 From: SourceCodeBot Date: Thu, 3 Jun 2021 16:54:34 +0200 Subject: [PATCH 1493/3075] docs: add import notice for extension methods (#2042) * docs: add import notice for extension methods * fix: solved review discussions --- .../scala3-book/ca-extension-methods.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/_overviews/scala3-book/ca-extension-methods.md b/_overviews/scala3-book/ca-extension-methods.md index 7c8639e020..b860b4f928 100644 --- a/_overviews/scala3-book/ca-extension-methods.md +++ b/_overviews/scala3-book/ca-extension-methods.md @@ -50,6 +50,25 @@ Then in your code you use `circumference` just as though it was originally defin aCircle.circumference ``` +### Import extension method + +Imagine, that `circumference` is defined in package `lib`, you can import it by + +```scala +import lib.circumference + +aCircle.circumference +``` + +The compiler also support you if the import is missing by showing a detailed compilation error message such as the following: + +```text +value circumference is not a member of Circle, but could be made available as an extension method. + +The following import might fix the problem: + + import lib.circumference +``` ## Discussion From 38c8ef07dd499326b3a5a8660817d2bf02ee7d52 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Fri, 4 Jun 2021 12:17:43 +0200 Subject: [PATCH 1494/3075] Fix redirects --- _sips/all.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_sips/all.md b/_sips/all.md index ed26042765..8133c137af 100644 --- a/_sips/all.md +++ b/_sips/all.md @@ -2,8 +2,9 @@ layout: sips title: List of All SIPs -redirect_from: "/sips/sip-list.html" -redirect_from: "/sips/pending/index.html" +redirect_from: + - "/sips/sip-list.html" + - "/sips/pending/index.html" --- From 6b8bc3882609961746ea005ad9fb2fd94f03d027 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Fri, 4 Jun 2021 12:23:48 +0200 Subject: [PATCH 1495/3075] Fix redirects --- _tour/named-arguments.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_tour/named-arguments.md b/_tour/named-arguments.md index 3dc7a4a503..af82d72844 100644 --- a/_tour/named-arguments.md +++ b/_tour/named-arguments.md @@ -8,8 +8,9 @@ next-page: traits previous-page: default-parameter-values prerequisite-knowledge: function-syntax -redirect_from: "/tutorials/tour/named-arguments.html" -redirect_from: "/tutorials/tour/named-parameters.html" +redirect_from: + - "/tutorials/tour/named-arguments.html" + - "/tutorials/tour/named-parameters.html" --- When calling methods, you can label the arguments with their parameter names like so: From a480f7581acab3e49b5fa2d4169c76bafa41efc0 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Fri, 4 Jun 2021 12:24:22 +0200 Subject: [PATCH 1496/3075] Fix redirects --- _tour/tour-of-scala.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/_tour/tour-of-scala.md b/_tour/tour-of-scala.md index 2f23fdd254..59e4072e3a 100644 --- a/_tour/tour-of-scala.md +++ b/_tour/tour-of-scala.md @@ -7,9 +7,10 @@ num: 1 next-page: basics -redirect_from: "/tutorials/tour/tour-of-scala.html" -redirect_from: "/tutorials/tour/anonymous-function-syntax.html" -redirect_from: "/tutorials/tour/explicitly-typed-self-references.html" +redirect_from: + - "/tutorials/tour/tour-of-scala.html" + - "/tutorials/tour/anonymous-function-syntax.html" + - "/tutorials/tour/explicitly-typed-self-references.html" --- ## Welcome to the tour From 980dc6d1f9e9f53c63413a1c11c82b2bde24f496 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Fri, 4 Jun 2021 12:24:49 +0200 Subject: [PATCH 1497/3075] Fix redirects --- _tour/for-comprehensions.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_tour/for-comprehensions.md b/_tour/for-comprehensions.md index 54ed69f0bf..ce9a8849c5 100644 --- a/_tour/for-comprehensions.md +++ b/_tour/for-comprehensions.md @@ -7,8 +7,9 @@ num: 19 next-page: generic-classes previous-page: extractor-objects -redirect_from: "/tutorials/tour/for-comprehensions.html" -redirect_from: "/tutorials/tour/sequence-comprehensions.html" +redirect_from: + - "/tutorials/tour/for-comprehensions.html" + - "/tutorials/tour/sequence-comprehensions.html" --- Scala offers a lightweight notation for expressing *sequence comprehensions*. Comprehensions have the form `for (enumerators) yield e`, where `enumerators` refers to a semicolon-separated list of enumerators. An *enumerator* is either a generator which introduces new variables, or it is a filter. A comprehension evaluates the body `e` for each binding generated by the enumerators and returns a sequence of these values. From f51e92ee1dd4b976b036f83cf73b232df533604e Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Fri, 4 Jun 2021 12:25:14 +0200 Subject: [PATCH 1498/3075] Fix redirects --- _tour/abstract-type-members.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_tour/abstract-type-members.md b/_tour/abstract-type-members.md index 8cad19b617..77dedcc386 100644 --- a/_tour/abstract-type-members.md +++ b/_tour/abstract-type-members.md @@ -8,8 +8,9 @@ previous-page: inner-classes topics: abstract type members prerequisite-knowledge: variance, upper-type-bound -redirect_from: "/tutorials/tour/abstract-types.html" -redirect_from: "/tour/abstract-types.html" +redirect_from: + - "/tutorials/tour/abstract-types.html" + - "/tour/abstract-types.html" --- Abstract types, such as traits and abstract classes, can in turn have abstract type members. From 2eee485ffb573391f00861027d85d61b53afc1a5 Mon Sep 17 00:00:00 2001 From: Philippus Baalman Date: Fri, 4 Jun 2021 14:39:30 +0200 Subject: [PATCH 1499/3075] Fix redirects --- _overviews/FAQ/index.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/_overviews/FAQ/index.md b/_overviews/FAQ/index.md index b9eca9a551..0e4b7200ad 100644 --- a/_overviews/FAQ/index.md +++ b/_overviews/FAQ/index.md @@ -2,14 +2,15 @@ layout: singlepage-overview title: Scala FAQ permalink: /tutorials/FAQ/index.html -redirect_from: "/tutorials/FAQ/breakout.html" -redirect_from: "/tutorials/FAQ/chaining-implicits.html" -redirect_from: "/tutorials/FAQ/collections.html" -redirect_from: "/tutorials/FAQ/context-bounds.html" -redirect_from: "/tutorials/FAQ/finding-implicits.html" -redirect_from: "/tutorials/FAQ/finding-symbols.html" -redirect_from: "/tutorials/FAQ/stream-view.html" -redirect_from: "/tutorials/FAQ/yield.html" +redirect_from: + - "/tutorials/FAQ/breakout.html" + - "/tutorials/FAQ/chaining-implicits.html" + - "/tutorials/FAQ/collections.html" + - "/tutorials/FAQ/context-bounds.html" + - "/tutorials/FAQ/finding-implicits.html" + - "/tutorials/FAQ/finding-symbols.html" + - "/tutorials/FAQ/stream-view.html" + - "/tutorials/FAQ/yield.html" --- Frequently asked questions, with _brief_ answers and/or links to From c3fd91cc9b2c2148410373ebab177cc85597b30e Mon Sep 17 00:00:00 2001 From: Alessandro Buggin <830963+abuggin@users.noreply.github.com> Date: Thu, 10 Jun 2021 14:21:41 +0100 Subject: [PATCH 1500/3075] Minor typo --- _overviews/scala3-migration/tooling-migration-mode.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-migration/tooling-migration-mode.md b/_overviews/scala3-migration/tooling-migration-mode.md index 045ede947b..b8c2cb0904 100644 --- a/_overviews/scala3-migration/tooling-migration-mode.md +++ b/_overviews/scala3-migration/tooling-migration-mode.md @@ -37,7 +37,7 @@ where possible standard options include: The `-source:3.0-migration` option makes the compiler forgiving on most of the dropped features, printing warnings in place of errors. Each warning is a strong indication that the compiler is even capable of safely rewriting the deprecated pieces of code into their cross-compiling counterparts. -We call this the **Scala 3 migration compialtion**. +We call this the **Scala 3 migration compilation**. ## Automatic rewrites From 262f04216954d5ee7651300c3f8fac0b17199883 Mon Sep 17 00:00:00 2001 From: vincenzobaz Date: Fri, 28 May 2021 10:49:25 +0200 Subject: [PATCH 1501/3075] Use GitHub actions instead of Travis CI --- _overviews/contributors/index.md | 354 ++++++++++++------------------- 1 file changed, 135 insertions(+), 219 deletions(-) diff --git a/_overviews/contributors/index.md b/_overviews/contributors/index.md index 0d31996273..4421211e15 100644 --- a/_overviews/contributors/index.md +++ b/_overviews/contributors/index.md @@ -46,62 +46,47 @@ use the correct sbt version. ## Setup Continuous Integration The first reason for setting up a continuous integration (CI) server is to systematically run tests on pull requests. -Examples of CI servers that are free for open source projects are [Travis CI](https://travis-ci.org), -[Drone](https://drone.io) or [AppVeyor](https://appveyor.com). +Examples of CI servers that are free for open source projects are [GitHub Actions](https://github.com/features/actions), +[Travis CI](https://travis-ci.com), [Drone](https://drone.io) or [AppVeyor](https://appveyor.com). -Our example uses Travis CI. To enable Travis CI on your project, go to [travis-ci.org](https://travis-ci.org/), -sign up using your GitHub account, and enable your project repository. Then, add a `.travis.yml` file to your -repository with the following content: +Our example uses Github Actions. This feature is enabled by default on GitHub repositories. You can verify if that is +the case and enable them in the *Actions* section of the *Settings* tab of the repository. -~~~ yaml -language: scala -~~~ - -Push your changes and check that Travis CI triggers a build for your repository. - -Travis CI tries to guess which build tool your project uses and executes a default command to run the project tests. -For instance, if your repository contains a `build.sbt` file in the root directory, Travis CI executes the -`sbt ++$TRAVIS_SCALA_VERSION test` command, where the `TRAVIS_SCALA_VERSION` variable is, by default, set to an -arbitrary Scala version (`2.12.8`, at the time these lines are written), which could be inconsistent with the -`scalaVersion` defined in your `build.sbt` file. - -To avoid this potential inconsistency, you want to use one Scala version definition as a single source of truth. -For instance, the [sbt-travisci](https://github.com/dwijnand/sbt-travisci) plugin lets you define the Scala version -in the `.travis.yml` file, and then forwards this version to your sbt build definition. Alternatively, you can -override the default command run by Travis CI to use the Scala version defined by the `scalaVersion` settings of -your build. +With Actions enabled, you can create a *workflow definition file*. A **workflow** is an automated procedure, +composed of one or more jobs. A **job** is a set of sequential steps that are executed on the same runner. +A **step** is an individual task that can run commands; a step can be either an *action* or a shell command. +An **action** is the smallest building block of a workflow, it is possible to reuse community actions or to +define new ones. -The latter approach is the one used in this guide. Override the command run by Travis CI by adding the folliwng -lines to your `.travis.yml` file: +To create a workflow, create a *yaml* file in the directory `.github/workflows/` in the repository, for example +`.github/workflows/ci.yml` with the following content: ~~~ yaml +name: Continuous integration +on: push + jobs: - include: - - stage: test - script: sbt test + Tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 # Retrieve the content of the repository + - uses: olafurpg/setup-scala@v11 # Set up a jdk and sbt + - name: unit tests # Custom action consisting of a shell command + run: sbt +test ~~~ -Travis CI will now execute the `sbt test` command, which uses the Scala version from the build definition. +This workflow is called *Continuous integration* and it will run every time one or more commits are pushed to +the repository. It contains only one job called *Tests*, which will run on an Ubuntu runner and that is composed +of three actions. `setup-scala` uses the sbt version specified in `project/build.properties` and the Scala +version defined in your `build.sbt`. -Last, an important thing to setup is caching, to avoid the CI server to re-download your project dependencies each -time it runs. For instance, in case you use sbt, you can instruct Travis CI to save the content of the `~/.ivy2/` -and `~/.sbt/` directories across builds by adding the following lines to your `.travis.yml` file: - -~~~ yaml -# These directories are cached at the end of the build -cache: - directories: - - $HOME/.ivy2/cache - - $HOME/.sbt -before_cache: - # Cleanup the cached directories to avoid unnecessary cache updates - - rm -fv $HOME/.ivy2/.sbt.ivy.lock - - find $HOME/.ivy2/cache -name "ivydata-*.properties" -print -delete - - find $HOME/.sbt -name "*.lock" -print -delete -~~~ +The worfklow above will run at any push to any branch of the repository. You can +specify the branch or add more triggers such as pull requests, releases, tags or +schedules. More information about workflow triggers is available [here](https://docs.github.com/en/actions/reference/events-that-trigger-workflows). +while the `setup-scala` action is hosted [in this repository](https://github.com/olafurpg/setup-scala). For reference, here is our complete -[.travis.yml example file](https://github.com/scalacenter/library-example/blob/master/.travis.yml). +[workflow example file](https://github.com/scalacenter/library-example/blob/master/.github/.workflows/ci.yml). ## Publish a Release @@ -125,7 +110,7 @@ sign the binaries. ### Create a Sonatype Account and Project Follow the instructions given on the [OSSRH Guide](https://central.sonatype.org/pages/ossrh-guide.html#initial-setup) -to create a new Sonatype account (unless you already have one) and to +to create a new Sonatype account (unless you already have one) and to [create a new project ticket](https://issues.sonatype.org/secure/CreateIssue.jspa?issuetype=21&pid=10134). This latter step is where you define the `groupId` that you will release to. You can use a domain name that you already own, otherwise a common practice is to use `io.github.(username)` (where `(username)` is replaced with your GitHub @@ -143,7 +128,7 @@ This step has to be performed only once per person. ### Setup Your Project -In case you use sbt, we recommend using the [sbt-sonatype](https://github.com/xerial/sbt-sonatype) +In case you use sbt, we recommend using the [sbt-sonatype](https://github.com/xerial/sbt-sonatype) and [sbt-pgp](https://www.scala-sbt.org/sbt-pgp/) plugins to publish your artifacts. Add the following dependencies to your `project/plugins.sbt` file: @@ -201,7 +186,7 @@ And make sure your build does **not** define the `version` setting. With this setup, the process for cutting a release is the following. Create a Git tag whose name begins with a lowercase `v` followed by the version number: - + ~~~ bash $ git tag v0.1.0 ~~~ @@ -236,9 +221,8 @@ Continuous publication addresses these issues by delegating the publication proc follows: any contributor with write access to the repository can cut a release by pushing a Git tag, the CI server first checks that the tests pass and then runs the publication commands. -The remaining sections show how to setup Travis CI for continuous publication on Sonatype. You can find instructions -for other CI servers and repositories in the [sbt-release-early](https://github.com/scalacenter/sbt-release-early) -plugin documentation. +The remaining sections show how to setup GitHub Actions for continuous publication on Sonatype. You can find instructions +for Travis CI in the [sbt-ci-release](https://github.com/olafurpg/sbt-ci-release) plugin documentation. ### Setup the CI Server @@ -247,28 +231,14 @@ it is possible to securely give this information by using the secret management #### Export Your Sonatype Account Credentials -The `SONATYPE_USERNAME` and `SONATYPE_PASSWORD` environment variables are recognized by the `sbt-sonatype` -plugin, as documented [here](https://github.com/xerial/sbt-sonatype#homesbtsbt-version-013-or-10sonatypesbt-1). +Create two [GitHub Encrypted secrets](https://docs.github.com/en/actions/reference/encrypted-secrets) +for your Sonatype account credentials: `SONATYPE_USERNAME` and `SONATYPE_PASSWORD`. +To do so, go to the *Settings* tab of the repository and select *Secrets* on the left panel. +You can then use the button *New repository secret* to open the secret creation menu where you will enter +the name of the secret and its content. -With Travis CI, you will have to install the [Travis CLI](https://github.com/travis-ci/travis.rb#installation). - -Then, run the following commands from your project root directory to add your Sonatype credentials as -environment variables to your `.travis.yml` file in an encrypted form: - -~~~ bash -$ travis encrypt SONATYPE_USERNAME="(Sonatype user name)" --add -$ travis encrypt SONATYPE_PASSWORD="(Sonatype password)" --add -~~~ - -(Put your actual user name and password in place of `(Sonatype user name)` and `(Sonatype password)`) - -The `--add` option updates your `.travis.yml` file with entries like the following: - -~~~ yaml -env: - global: - - secure: "dllL1w+pZT6yTBYwy5hX07t8r0JL5Cqer6YgYnXJ+q3OhSGUs7ul2fDUiqVxGIgUpTij1cGwBmoJOTbRk2V/be4+3Ua4ZNrAxjNF2ehqUcV5KdC3ufTTTXX0ZoL9MqEIb+GKzKtPqbzR4uly/5q5NbV7J1GeZRhummnx87POl6yH4kmXTpahig7vvnwN5dLanMshRb2Z8tO8kF4SnC31QuNBDQLnS89PEajHQu+LRAJloYvcikm+NeUj79m64CYg9JZdrHvZpIYKOMY1twT+lYoerqzG+asiNE1WrDs/We1RFVgcrKLpEThcvuIxuuPKhu24+0KteAX+7z/ulT0lndyBRfuuDjHV844LrNbjhnTB64V1uF7aEdaEZRLTsFQnFZqzpoqYqxzgfow9LN/kU5CMJX1R4wwf3YgR1VC9ZfjZnu0Pbt24g48I+72ZDNk3oRZoPsN9AtovwdZcg7TgU/iPcHNKSNhEZRP6ryhv/9aX3URLkfhnDaJmTXAnC3YCYt5cGo0FBUHARA+AHcas14Dx95bFSbH7EBivb2LiDmi44goRCWR4p+vNSBJ6Ak1NZz/+paai0pXDG6S/VdqwGSmmfjn7m9H3L5c8X5xNich9qtZbWz0fj2baZGq/doA8KE91JCzX11p/9fKNzbVivQZdsw3C3ZWDjkMZM+hl++0=" -~~~ +Repository Secrets allow us to safely store confidential information and to expose +it to Actions workflows without the risk of committing them to git history. #### Export Your PGP Key Pair @@ -285,72 +255,65 @@ uid Julien Richard-Foy In my case, I have one key pair, whose ID is `BE614499`. -Export your public and private keys into files, in a `ci` directory: - -~~~ bash -$ mkdir ci -$ gpg -a --export (key ID) > ci/pubring.asc -$ gpg -a --export-secret-keys (key ID) > ci/secring.asc -~~~ +Then: + + 1. Create a new Secret containing the passphrase of your PGP key named `PGP_PASSPHRASE`. + 2. Create a new Secret containing the base64 encoded secret of your private key, which you can obtain + by running: +``` +# macOS +gpg --armor --export-secret-keys $LONG_ID | base64 +# Ubuntu (assuming GNU base64) +gpg --armor --export-secret-keys $LONG_ID | base64 -w0 +# Arch +gpg --armor --export-secret-keys $LONG_ID | base64 | sed -z 's;\n;;g' +# FreeBSD (assuming BSD base64) +gpg --armor --export-secret-keys $LONG_ID | base64 +# Windows +gpg --armor --export-secret-keys %LONG_ID% | openssl base64 +``` + 3. Publish your public key signature to a public server, for example [http://keyserver.ubuntu.com:11371](http://keyserver.ubuntu.com:11371/). + You can obtain the signature by running: +``` +# macOS and linux +gpg --armor --export $LONG_ID +# Windows +gpg --armor --export %LONG_ID% +``` (Replace `(key ID)` with **your** key ID) -Add the `ci/pubring.asc` file (which contains your public key) to your repository. The `secring.asc` file -(which contains your private key) should **not** be added as it is to the repository, so make sure it will -be ignored by Git by adding it to the `.gitignore` file: - -~~~ -ci/secring.asc -~~~ - -Encrypt it with the `travis` tool: - -~~~ bash -$ travis encrypt-file ci/secring.asc ci/secring.asc.enc --add -~~~ - -As advised in the command output, make sure to add the `secring.asc.enc` to the git repository. - -The `--add` option above adds a line like the following to your `.travis.yml` file: - -~~~ diff -before_install: - - openssl aes-256-cbc -K $encrypted_602f530300eb_key -iv $encrypted_602f530300eb_iv -in ci/secring.asc.enc -out ci/secring.asc -d -~~~ - -Finally, add export your PGP passphrase to the `.travis.yml` file: - -~~~ -$ travis encrypt PGP_PASSPHRASE="(your passphrase)" --add -~~~ - -(Replace `(your passphrase)` with your actual passphrase) #### Publish From the CI Server -On Travis CI, you can define a -[conditional stage](https://docs.travis-ci.com/user/build-stages/#specifying-stage-order-and-conditions) -publishing the library when a tag is pushed: +On GitHub Actions, you can define a workflow to publish the library when a tag is pushed: ~~~ yaml -jobs: - include: - - stage: test - script: sbt test - - stage: deploy - if: tag =~ ^v - script: sbt publishSigned sonatypeRelease -~~~ +# .github/workflows/release.yml +name: Continuous publication +on: + push: + branches: ['**'] + tags: [v*] -The last step is to tell your build definition how to retrieve the PGP passphrase from the `PGP_PASSPHRASE` -environment variable and to use the `pubring.asc` and `secring.asc` files as the PGP key pair. -Include the following settings in your `build.sbt` file: - -~~~ scala -pgpPublicRing := file("ci/pubring.asc") -pgpSecretRing := file("ci/secring.asc") -pgpPassphrase := sys.env.get("PGP_PASSPHRASE").map(_.toArray) -~~~ +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 # fetch all tags, required for sbt-dynver + - uses: olafurpg/setup-scala@v11 + - run: sbt ci-release + env: + PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} + PGP_SECRET: ${{ secrets.PGP_SECRET }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} +~~~ + +The `env` statement exposes the secrets you defined earlier to the publication process through +environment variables. ### Cut a Release @@ -374,19 +337,7 @@ scalaVersion := crossScalaVersions.value.head ~~~ The second line makes sbt use by default the first Scala version of the `crossScalaVersions`. - -Modify the CI jobs to use all the Scala versions of your build definition by using the `+` prefix, -when appropriate: - -~~~ yaml -jobs: - include: - - stage: test - script: sbt +test - - stage: deploy - if: tag =~ ^v - script: sbt +publishSigned sonatypeRelease -~~~ +The CI job will use all the Scala versions of your build definition. ## Publish Online Documentation @@ -589,78 +540,28 @@ can browse it at [https://scalacenter.github.io/library-example/](https://scalac ### Continuous Publication -You need to grant the CI job write access to the Git repository hosting the documentation. This can be achieved -by creating an SSH key that the CI job can use to push the website to GitHub. - -Create an SSH key: +You can extend `.github/workflows/release.yml` to automatically publish documentation to GitHub pages. +To do so, add another job: -~~~ bash -$ ssh-keygen -t rsa -b 4096 -C "sbt-site@travis" -f ci/travis-key -~~~ - -Make sure to **not** define a passphrase (just leave it empty and press enter), and to add the private -key (the `ci/travis-key` file) to your `.gitignore`: - -~~~ -ci/secring.asc -ci/travis-key -~~~ +```yml +# .github/workflows/release.yml +name: Continuous publication -Add the public key, `ci/travis-key.pub`, in the Deploy Keys section of your GitHub project’s settings page: - -![](/resources/images/travis-publishing-key.png) - -Make sure you “allow write access” by checking the box. - -The private key has to be added to the repository, like we did with the PGP private key. Unfortunately, due -to a limitation of Travis CI, you can not add several encrypted files. The -[workaround](https://docs.travis-ci.com/user/encrypting-files/#encrypting-multiple-files) consists in -creating an archive containing all the files to encrypt. In your case, you want to encrypt the PGP -key and the SSH key into a single `ci/secrets.tar` file: - -~~~ bash -$ tar cvf ci/secrets.tar ci/secring.asc ci/travis-key -$ travis encrypt-file ci/secrets.tar ci/secrets.tar.enc --add -~~~ - -Make sure to add the `ci/secrets.tar` file to your `.gitignore`: - -~~~ -ci/secring.asc -ci/travis-key -ci/secrets.tar -~~~ - -Finally, update the `.travis.yml` file to unpack the archive and push the documentation website -on releases: - -~~~ yaml jobs: - include: - - stage: test - # Run tests for all Scala versions - script: sbt +test - name: "Tests" - # Check that the documentation can be built - - script: sbt makeSite - name: "Documentation" - - - stage: deploy - if: tag =~ ^v - script: - # decrypt PGP secret key and GitHub SSH key - - openssl aes-256-cbc -K $encrypted_602f530300eb_key -iv $encrypted_602f530300eb_iv -in ci/secrets.tar.enc -out ci/secrets.tar -d - - tar xvf ci/secrets.tar - # load the key in the ssh-agent - - chmod 600 ci/travis-key - - eval "$(ssh-agent -s)" - - ssh-add ci/travis-key - # perform deployment - - sbt makeSite +publishSigned sonatypeRelease ghpagesPushSite -~~~ - -(Replace the `$encrypted_602f530300eb_key` and `$encrypted_602f530300eb_iv` variables with the ones produced by the -`travis encrypt-file` command) + release: # The release job is not changed, you can find it above + publishSite: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: olafurpg/setup-scala@v11 + - name: Generate site + run: sbt makeSite + - uses: JamesIves/github-pages-deploy-action@4.1.3 + with: + branch: gh-pages + folder: target/site + +``` As usual, cut a release by pushing a Git tag. The CI server will run the tests, publish the binaries and update the online documentation. @@ -699,14 +600,19 @@ addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "1.5.1") In the `CONTRIBUTING.md` file, mention that you use that code formatter and encourage users to use the “format on save” feature of their editor. -In your `.travis.yml` file, add a first stage checking that the code has been properly formatted: +In your `.github/workflows/ci.yml` file, add a step checking that the code has been properly formatted: ~~~ yaml +# .github/workflows/ci.yml +# The three periods `...` indicate the parts of file that do not change +# from the snippets above and they are omitted for brevity jobs: - include: - - - stage: style - script: sbt scalafmtCheck + ci: + # ... + steps: + # ... + - name: Code style + run: sbt scalafmtCheck ~~~ ## Evolve @@ -732,11 +638,21 @@ Configure it as follow, in `build.sbt`: mimaPreviousArtifacts := previousStableVersion.value.map(organization.value %% name.value % _).toSet ~~~ -Last, add the following job to the “test” stage, in the `.travis.yml` file: +Last, add the following step to the job `ci` of the `Continuous integration` workflow, in the `.github/workflows/ci.yml` file: ~~~ yaml - - script: sbt mimaReportBinaryIssues - name: "Binary compatibility" +# .github/workflows/ci.yml +# The three periods `...` indicate the parts of file that do not change +# from the snippets above and they are omitted for brevity + +# ... +jobs: + ci: + # ... + steps: + # ... + - name: Binary compatibility + run: sbt mimaReportBinaryIssues ~~~ This will check that pull requests don’t make changes that are binary incompatible with the From 797f0f77b1f1b3276c6d281718c1aefaa40ffcc3 Mon Sep 17 00:00:00 2001 From: vincenzobaz Date: Wed, 9 Jun 2021 16:22:36 +0200 Subject: [PATCH 1502/3075] t# This is a combination of 3 commits. Drop Scala 2.11 --- _overviews/contributors/index.md | 41 +++++++++++++++++++------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/_overviews/contributors/index.md b/_overviews/contributors/index.md index 4421211e15..1c94648972 100644 --- a/_overviews/contributors/index.md +++ b/_overviews/contributors/index.md @@ -50,7 +50,9 @@ Examples of CI servers that are free for open source projects are [GitHub Action [Travis CI](https://travis-ci.com), [Drone](https://drone.io) or [AppVeyor](https://appveyor.com). Our example uses Github Actions. This feature is enabled by default on GitHub repositories. You can verify if that is -the case and enable them in the *Actions* section of the *Settings* tab of the repository. +the case in the *Actions* section of the *Settings* tab of the repository. +If *Disable all actions* is checked, then Actions are not enabled and you can activate them +by selecting *Allow all actions*, *Allow local actions only* or *Allow select actions*. With Actions enabled, you can create a *workflow definition file*. A **workflow** is an automated procedure, composed of one or more jobs. A **job** is a set of sequential steps that are executed on the same runner. @@ -66,7 +68,7 @@ name: Continuous integration on: push jobs: - Tests: + ci: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 # Retrieve the content of the repository @@ -75,18 +77,23 @@ jobs: run: sbt +test ~~~ -This workflow is called *Continuous integration* and it will run every time one or more commits are pushed to -the repository. It contains only one job called *Tests*, which will run on an Ubuntu runner and that is composed -of three actions. `setup-scala` uses the sbt version specified in `project/build.properties` and the Scala -version defined in your `build.sbt`. +This workflow is called *Continuous integration* and it will run every time one +or more commits are pushed to the repository. It contains only one job called +*ci*, which will run on an Ubuntu runner and that is composed of three +actions. The action `setup-scala` installs the sbt launcher in the runner. Then +the job runs `sbt +test`, which loads the sbt version specified in +`project/build.properties`, and runs the project tests using the Scala version +defined in the file `build.sbt`. -The worfklow above will run at any push to any branch of the repository. You can -specify the branch or add more triggers such as pull requests, releases, tags or -schedules. More information about workflow triggers is available [here](https://docs.github.com/en/actions/reference/events-that-trigger-workflows). -while the `setup-scala` action is hosted [in this repository](https://github.com/olafurpg/setup-scala). +The workflow above will run at any push to any branch of the repository. You +can specify the branch or add more triggers such as pull requests, releases, +tags or schedules. More information about workflow triggers is available +[here](https://docs.github.com/en/actions/reference/events-that-trigger-workflows). +while the `setup-scala` action is hosted [in this +repository](https://github.com/olafurpg/setup-scala). -For reference, here is our complete -[workflow example file](https://github.com/scalacenter/library-example/blob/master/.github/.workflows/ci.yml). +For reference, here is our complete [workflow example +file](https://github.com/scalacenter/library-example/blob/master/.github/.workflows/ci.yml). ## Publish a Release @@ -156,7 +163,7 @@ import xerial.sbt.Sonatype._ sonatypeProjectHosting := Some(GitHubHosting("scalacenter", "library-example", "julien.richard-foy@epfl.ch")) // publish to the sonatype repository -publishTo := sonatypePublishTo.value +publishTo := sonatypePublishToBundle.value ~~~ Put your Sonatype credentials in a `$HOME/.sbt/1.0/sonatype.sbt` file: @@ -289,7 +296,7 @@ gpg --armor --export %LONG_ID% On GitHub Actions, you can define a workflow to publish the library when a tag is pushed: ~~~ yaml -# .github/workflows/release.yml +# .github/workflows/publish.yml name: Continuous publication on: push: @@ -332,7 +339,7 @@ If you have written a library, you probably want it to be usable from several Sc Define the versions you want to support in the `crossScalaVersions` setting, in your `build.sbt` file: ~~~ scala -crossScalaVersions := Seq("2.12.8", "2.11.12") +crossScalaVersions := Seq("2.13.6", "2.12.8") scalaVersion := crossScalaVersions.value.head ~~~ @@ -540,11 +547,11 @@ can browse it at [https://scalacenter.github.io/library-example/](https://scalac ### Continuous Publication -You can extend `.github/workflows/release.yml` to automatically publish documentation to GitHub pages. +You can extend `.github/workflows/publish.yml` to automatically publish documentation to GitHub pages. To do so, add another job: ```yml -# .github/workflows/release.yml +# .github/workflows/publish.yml name: Continuous publication jobs: From 5c24940560a5107139bf93364e562b428a7257a4 Mon Sep 17 00:00:00 2001 From: vincenzobaz Date: Fri, 11 Jun 2021 11:36:15 +0200 Subject: [PATCH 1503/3075] Update dependencies --- _overviews/contributors/index.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/_overviews/contributors/index.md b/_overviews/contributors/index.md index 1c94648972..76eb540b80 100644 --- a/_overviews/contributors/index.md +++ b/_overviews/contributors/index.md @@ -72,7 +72,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 # Retrieve the content of the repository - - uses: olafurpg/setup-scala@v11 # Set up a jdk and sbt + - uses: olafurpg/setup-scala@v12 # Set up a jdk and sbt - name: unit tests # Custom action consisting of a shell command run: sbt +test ~~~ @@ -140,8 +140,8 @@ and [sbt-pgp](https://www.scala-sbt.org/sbt-pgp/) plugins to publish your artifa dependencies to your `project/plugins.sbt` file: ~~~ scala -addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "2.4") -addSbtPlugin("com.jsuereth" % "sbt-pgp" % "1.1.0") +addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.7") +addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.1.1") ~~~ And make sure your build fulfills the [Sonatype requirements](https://central.sonatype.org/publish/requirements) @@ -183,7 +183,7 @@ Last, we recommend using the [sbt-dynver](https://github.com/dwijnand/sbt-dynver of your releases. Add the following dependency to your `project/plugins.sbt` file: ~~~ scala -addSbtPlugin("com.dwijnand" % "sbt-dynver" % "3.1.0") +addSbtPlugin("com.dwijnand" % "sbt-dynver" % "4.1.1") ~~~ And make sure your build does **not** define the `version` setting. @@ -310,7 +310,7 @@ jobs: - uses: actions/checkout@v2 with: fetch-depth: 0 # fetch all tags, required for sbt-dynver - - uses: olafurpg/setup-scala@v11 + - uses: olafurpg/setup-scala@v12 - run: sbt ci-release env: PGP_PASSPHRASE: ${{ secrets.PGP_PASSPHRASE }} @@ -339,7 +339,7 @@ If you have written a library, you probably want it to be usable from several Sc Define the versions you want to support in the `crossScalaVersions` setting, in your `build.sbt` file: ~~~ scala -crossScalaVersions := Seq("2.13.6", "2.12.8") +crossScalaVersions := Seq("2.13.6", "2.12.14") scalaVersion := crossScalaVersions.value.head ~~~ @@ -372,8 +372,8 @@ most other documentation generators, which are based on Ruby, Node.js or Python) To install Paradox and sbt-site, add the following lines to your `project/plugins.sbt` file: ~~~ scala -addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "1.3.2") -addSbtPlugin("com.lightbend.paradox" % "sbt-paradox" % "0.4.4") +addSbtPlugin("com.typesafe.sbt" % "sbt-site" % "1.4.1") +addSbtPlugin("com.lightbend.paradox" % "sbt-paradox" % "0.9.2") ~~~ And then add the following configuration to your `build.sbt` file: @@ -560,7 +560,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - uses: olafurpg/setup-scala@v11 + - uses: olafurpg/setup-scala@v12 - name: Generate site run: sbt makeSite - uses: JamesIves/github-pages-deploy-action@4.1.3 @@ -601,7 +601,7 @@ For instance, to use [scalafmt](https://scalameta.org/scalafmt/), add the follow file: ~~~ scala -addSbtPlugin("com.geirsson" % "sbt-scalafmt" % "1.5.1") +addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2") ~~~ In the `CONTRIBUTING.md` file, mention that you use that code formatter and encourage users to use the “format @@ -636,7 +636,7 @@ break this versioning policy. Add the `sbt-mima-plugin` to your build with the f `project/plugins.sbt` file: ~~~ scala -addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.3.0") +addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.9.2") ~~~ Configure it as follow, in `build.sbt`: From f0ee521a5c99065fc84ddb3cd7ed84af9706d12f Mon Sep 17 00:00:00 2001 From: "Lan, Jian" <45252210+ShapelessCat@users.noreply.github.com> Date: Sat, 12 Jun 2021 01:22:07 -0700 Subject: [PATCH 1504/3075] Fix why-scala-3.md The second `LinearSeq` of the clause "traits like `LinearSeq` and `LinearSeq`" should be another trait. --- _overviews/scala3-book/why-scala-3.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-book/why-scala-3.md b/_overviews/scala3-book/why-scala-3.md index 1c23d1e7f0..e5f317f9f3 100644 --- a/_overviews/scala3-book/why-scala-3.md +++ b/_overviews/scala3-book/why-scala-3.md @@ -45,7 +45,7 @@ For instance, a `List` is defined as a class---technically it’s an abstract cl val x = List(1, 2, 3) ``` -However, what appears to the programmer to be a simple `List` is actually built from a combination of several specialized types, including an abstract class named `AbstractSeq`, traits like `LinearSeq` and `LinearSeq`, and more. +However, what appears to the programmer to be a simple `List` is actually built from a combination of several specialized types, including an abstract class named `AbstractSeq`, traits like `LinearSeq` and `LinearSeqOps`, and more. Those types are similarly composed of other small, modular units of code. In addition to building a type like `List` from a series of modular traits, the `List` API also consists of dozens of other methods, many of which are higher-order functions: From 273a57fd4fa472fc3248a1a26703daeaa593ced4 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Wed, 9 Jun 2021 18:15:48 +0200 Subject: [PATCH 1505/3075] Suggestions in the Scala book MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I’ve reviewed the chapters Methods, Functions, and Packaging and Imports. --- .../scala3-book/fun-anonymous-functions.md | 4 +- _overviews/scala3-book/fun-hofs.md | 32 ++++++------ .../scala3-book/fun-write-map-function.md | 4 +- _overviews/scala3-book/methods-intro.md | 2 +- .../scala3-book/methods-main-methods.md | 4 +- _overviews/scala3-book/methods-most.md | 25 ++++----- _overviews/scala3-book/packaging-imports.md | 51 +++++++++++-------- 7 files changed, 65 insertions(+), 57 deletions(-) diff --git a/_overviews/scala3-book/fun-anonymous-functions.md b/_overviews/scala3-book/fun-anonymous-functions.md index c771c1458c..39d87da216 100644 --- a/_overviews/scala3-book/fun-anonymous-functions.md +++ b/_overviews/scala3-book/fun-anonymous-functions.md @@ -116,7 +116,7 @@ In other examples, you can simplify your anonymous functions further. For instance, beginning with the most explicit form, you can print each element in `ints` using this anonymous function with the `List` class `foreach` method: ```scala -ints.foreach((i:Int) => println(i)) +ints.foreach((i: Int) => println(i)) ``` As before, the `Int` declaration isn’t required, and because there’s only one argument, the parentheses around `i` aren’t needed: @@ -131,7 +131,7 @@ Because `i` is used only once in the body of the function, the expression can be ints.foreach(println(_)) ``` -Finally, if an anonymous function consists of one statement that takes a single argument, you don’t need to explicitly name and specify the argument, so the statement can finally be reduced to this: +Finally, if an anonymous function consists of one method call that takes a single argument, you don’t need to explicitly name and specify the argument, so you can finally write only the name of the method (here, `println`): ```scala ints.foreach(println) diff --git a/_overviews/scala3-book/fun-hofs.md b/_overviews/scala3-book/fun-hofs.md index c8d93c46ef..0985c38ea2 100644 --- a/_overviews/scala3-book/fun-hofs.md +++ b/_overviews/scala3-book/fun-hofs.md @@ -37,7 +37,7 @@ As a beneficial side effect of this discussion, once you’re comfortable with t To understand how higher-order functions work, it helps to dig into an example. For instance, you can understand the type of functions `filter` accepts by looking at its Scaladoc. -Here’s the `filter` definition in the `List` class: +Here’s the `filter` definition in the `List[A]` class: ```scala def filter(p: (A) => Boolean): List[A] @@ -102,7 +102,7 @@ Here’s how this works: It’s just like naming a `String` parameter `s` or an `Int` parameter `i`. - The type signature of `f` specifies the *type* of the functions this method will accept. - The `()` portion of `f`’s signature (on the left side of the `=>` symbol) states that `f` takes no input parameters. -- The `Unit` portion of the signature (on the right side of the `=>` symbol) indicates that `f` should return nothing. +- The `Unit` portion of the signature (on the right side of the `=>` symbol) indicates that `f` should not return a meaningful result. - Looking back at the body of the `sayHello` method (on the right side of the `=` symbol), the `f()` statement there invokes the function that’s passed in. Now that we’ve defined `sayHello`, let’s create a function to match `f`’s signature so we can test it. @@ -148,7 +148,7 @@ The only thing to do now is see a few more examples of how to define different t In this method: ```scala -def sayHello(f: () => Unit) +def sayHello(f: () => Unit): Unit ``` We noted that the type signature for `f` is: @@ -157,7 +157,7 @@ We noted that the type signature for `f` is: () => Unit ``` -We know that this means, “a function that takes no input parameters and returns nothing (given by `Unit`).” +We know that this means, “a function that takes no input parameters and returns nothing meaningful (given by `Unit`).” To demonstrate more type signature examples, here’s a function that takes a `String` parameter and returns an `Int`: @@ -255,40 +255,40 @@ executeAndPrint(multiply, 3, 9) // prints 27 ## Function type signature consistency -A great thing about learning about Scala’s function type signatures is that the syntax you use to define function input parameters is the same syntax you use to write anonymous functions and function variables. +A great thing about learning about Scala’s function type signatures is that the syntax you use to define function input parameters is the same syntax you use to write function literals. -For instance, if you were to write an anonymous function that calculates the sum of two integers, you’d write it like this: +For instance, if you were to write a function that calculates the sum of two integers, you’d write it like this: ```scala -(Int, Int) => Int = (a, b) => a + b +val f: (Int, Int) => Int = (a, b) => a + b ``` That code consists of the type signature: ```` -(Int, Int) => Int = (a, b) => a + b ------------------ +val f: (Int, Int) => Int = (a, b) => a + b + ----------------- ```` The input parameters: ```` -(Int, Int) => Int = (a, b) => a + b - ------ +val f: (Int, Int) => Int = (a, b) => a + b + ------ ```` and the body of the function: ```` -(Int, Int) => Int = (a, b) => a + b - ----- +val f: (Int, Int) => Int = (a, b) => a + b + ----- ```` -Scala’s consistency is shown here, where this anonymous function type signature: +Scala’s consistency is shown here, where this function type: ```` -(Int, Int) => Int = (a, b) => a + b ------------------ +val f: (Int, Int) => Int = (a, b) => a + b + ----------------- ```` is the same as the type signature you use to define a function input parameter: diff --git a/_overviews/scala3-book/fun-write-map-function.md b/_overviews/scala3-book/fun-write-map-function.md index 633d9b8fb8..74cab95213 100644 --- a/_overviews/scala3-book/fun-write-map-function.md +++ b/_overviews/scala3-book/fun-write-map-function.md @@ -66,7 +66,7 @@ As a bonus, notice that the `for` expression doesn’t do anything that depends Therefore, you can replace `Int` in the type signature with the generic type parameter `B`: ```scala -def map[A,B](f: (B) => A, xs: List[B]): List[A] = +def map[A, B](f: (B) => A, xs: List[B]): List[A] = for x <- xs yield f(x) ``` @@ -76,7 +76,7 @@ These examples demonstrate that `map` works as desired: ```scala def double(i : Int) = i * 2 -map(double, List(1, 2, 3)) // List(2,4,6) +map(double, List(1, 2, 3)) // List(2, 4, 6) def strlen(s: String) = s.length map(strlen, List("a", "bb", "ccc")) // List(1, 2, 3) diff --git a/_overviews/scala3-book/methods-intro.md b/_overviews/scala3-book/methods-intro.md index a6bf3e2fff..1c1414746c 100644 --- a/_overviews/scala3-book/methods-intro.md +++ b/_overviews/scala3-book/methods-intro.md @@ -9,7 +9,7 @@ next-page: methods-most In Scala 2, _methods_ can be defined inside classes, traits, objects, case classes, and case objects. -But it gets better: In Scala 3 they can also be defined _outside_ any of those constructs with a new feature named Toplevel definitions. +But it gets better: In Scala 3 they can also be defined _outside_ any of those constructs; we say that they are "top-level" definitions, since they are not nested in another definition. In short, methods can now be defined anywhere. Many features of methods are demonstrated in the next section. diff --git a/_overviews/scala3-book/methods-main-methods.md b/_overviews/scala3-book/methods-main-methods.md index 1077e238a2..bee342a45f 100644 --- a/_overviews/scala3-book/methods-main-methods.md +++ b/_overviews/scala3-book/methods-main-methods.md @@ -11,7 +11,7 @@ next-page: methods-summary Scala 3 offers a new way to define programs that can be invoked from the command line: Adding a `@main` annotation to a method turns it into entry point of an executable program: ```scala -@main def hello = println("Hello, world") +@main def hello() = println("Hello, world") ``` Just save that line of code in a file named something like *Hello.scala*---the filename doesn’t have to match the method name---and compile it with `scalac`: @@ -81,7 +81,7 @@ Illegal command line: java.lang.NumberFormatException: For input string: "sixty" The Scala compiler generates a program from an `@main` method `f` as follows: - It creates a class named `f` in the package where the `@main` method was found. -- The class has a static method `main` with the usual signature: It takes an `Array[String]` as argument and returns `Unit`. +- The class has a static method `main` with the usual signature of a Java `main` method: it takes an `Array[String]` as argument and returns `Unit`. - The generated `main` method calls method `f` with arguments converted using methods in the `scala.util.CommandLineParser` object. For instance, the `happyBirthday` method above generates additional code equivalent to the following class: diff --git a/_overviews/scala3-book/methods-most.md b/_overviews/scala3-book/methods-most.md index ac2140a41b..233c51b847 100644 --- a/_overviews/scala3-book/methods-most.md +++ b/_overviews/scala3-book/methods-most.md @@ -7,16 +7,16 @@ previous-page: methods-intro next-page: methods-main-methods --- -This section introduces the various aspects of how to define and call methods in Scala 2. +This section introduces the various aspects of how to define and call methods in Scala 3. ## Defining Methods Scala methods have many features, including these: - Generic (type) parameters -- Automatically provided `using` parameters - Default parameter values - Multiple parameter groups +- Context-provided parameters - By-name parameters - ... @@ -63,7 +63,7 @@ The Scala collections classes have dozens of built-in methods. These examples show how to call them: ```scala -val x = List(1,2,3) +val x = List(1, 2, 3) x.size // 3 x.contains(1) // true @@ -102,7 +102,7 @@ res0: Int = 4 ``` Notice that there’s no need for a `return` statement at the end of the method. -Because almost everything in Scala is an _expression_---meaning that each line of code returns (or _evaluates to) a value---there’s no need to use `return`. +Because almost everything in Scala is an _expression_---meaning that each line of code returns (or _evaluates to_) a value---there’s no need to use `return`. This becomes more clear when you condense that method and write it on one line: @@ -118,6 +118,7 @@ The body of a method can use all the different features of the language: - `for` loops and `for` expressions - Variable assignments - Calls to other methods +- Definitions of other methods As an example of a real-world multiline method, this `getStackTraceAsString` method converts its `Throwable` input parameter into a well-formatted `String`: @@ -202,10 +203,10 @@ When a method takes no parameters, it’s said to have an _arity_ level of _arit Similarly, when a method takes one parameter it’s an _arity-1_ method. When you create arity-0 methods: -- If the method has side effects, such as calling `println`, declare the method with empty parentheses -- If the method does not have side effects---such as getting the size of a collection, which is similar to accessing a field on the collection---leave the parentheses off +- If the method performs side effects, such as calling `println`, declare the method with empty parentheses +- If the method does not perform side effects---such as getting the size of a collection, which is similar to accessing a field on the collection---leave the parentheses off -For example, this method has a side effect, so it’s declared with empty parentheses: +For example, this method performs a side effect, so it’s declared with empty parentheses: ```scala def speak() = println("hi") @@ -218,7 +219,7 @@ speak // error: "method speak must be called with () argument" speak() // prints "hi" ``` -While this is just a convention, following it dramatically improves code readability: It makes it easier to understand at a glance that an arity-0 method has side effects. +While this is just a convention, following it dramatically improves code readability: It makes it easier to understand at a glance that an arity-0 method performs side effects. {% comment %} Some of that wording comes from this page: https://docs.scala-lang.org/style/method-invocation.html @@ -233,7 +234,7 @@ Here’s a method named `isTruthy` that implements the Perl definitions of `true ```scala def isTruthy(a: Any) = - if a == 0 || a == "" then + if a == 0 || a == "" || a == false then false else true @@ -257,7 +258,7 @@ Here’s another version of `isTruthy`, written with a `match` expression : ```scala def isTruthy(a: Matchable) = a match - case 0 | "" => false + case 0 | "" | false => false case _ => true ``` @@ -279,7 +280,7 @@ d.speak() // prints "Woof" ``` Methods can also be marked as `private`. -This makes them private to the current class, and they can’t be overridden in subclasses: +This makes them private to the current class, so they can’t be called nor overridden in subclasses: ```scala class Animal: @@ -290,7 +291,7 @@ class Cat extends Animal: override def breathe() = println("Yo, I’m totally breathing") ``` -If you want to make a method private to the current class and also allow subclasses to override it, mark the method as `protected`, as shown with the `speak` method in this example: +If you want to make a method private to the current class and also allow subclasses to call it or override it, mark the method as `protected`, as shown with the `speak` method in this example: ```scala class Animal: diff --git a/_overviews/scala3-book/packaging-imports.md b/_overviews/scala3-book/packaging-imports.md index b34071123d..ef3b9a16c1 100644 --- a/_overviews/scala3-book/packaging-imports.md +++ b/_overviews/scala3-book/packaging-imports.md @@ -33,26 +33,33 @@ package com.acme.myapp.model class Person ... ``` -By convention, package names should be all lower case, and the formal naming convention is *...*. +By convention, package names should be all lower case, and the formal naming convention is *\.\.\.\*. Although it’s not required, package names typically follow directory structure names, so if you follow this convention, a `Person` class in this project will be found in a *MyApp/src/main/scala/com/acme/myapp/model/Person.scala* file. -### Curly brace packaging style +### Using multiple packages in the same file -The other way to declare packages in Scala is by using the curly brace namespace notation used in languages like C, C++, and C#: +The syntax shown above applies to the entire source file: all the definitions in the file +`Person.scala` belong to package `com.acme.myapp.model`, according to the package clause +at the beginning of the file. + +Alternatively, it is possible to write package clauses that apply only to the definitions +they contain: ```scala -package users { - package administrators { - class AdminUser - } - package normalusers { - class NormalUser - } -} +package users: + + package administrators: // the full name of this package is users.administrators + class AdminUser // the full name of this class is users.administrators.AdminUser + + package normalusers: // the full name of this package is users.normalusers + class NormalUser // the full name of this class is users.normalusers.NormalUser ``` +Note that the package names are followed by a colon, and that the defininitions within +a package are indented. + The advantages of this approach are that it allows for package nesting, and provides more obvious control of scope and encapsulation, especially within the same file. @@ -92,27 +99,27 @@ A note before moving on: In Scala you can import one member from a package like this: ```scala -import java.io.File +import scala.concurrent.Future ``` and multiple members like this: ```scala -import java.io.File -import java.io.IOException -import java.io.FileNotFoundException +import scala.concurrent.Future +import scala.concurrent.Promise +import scala.concurrent.blocking ``` When importing multiple members, you can import them more concisely like this: ```scala -import java.io.{File, IOException, FileNotFoundException} +import scala.concurrent.{Future, Promise, blocking} ``` -When you want to import everything from the *java.io* package, use this syntax: +When you want to import everything from the *scala.concurrent* package, use this syntax: ```scala -import java.io.* +import scala.concurrent.* ``` @@ -170,13 +177,13 @@ val res0: java.util.ArrayList[String] = [] Because those Java classes are hidden, you can also use the Scala `List`, `Set`, and `Map` classes without having a naming collision: ```scala -scala> val a = List(1,2,3) +scala> val a = List(1, 2, 3) val a: List[Int] = List(1, 2, 3) -scala> val b = Set(1,2,3) +scala> val b = Set(1, 2, 3) val b: Set[Int] = Set(1, 2, 3) -scala> val c = Map(1->1, 2->2) +scala> val c = Map(1 -> 1, 2 -> 2) val c: Map[Int, Int] = Map(1 -> 1, 2 -> 2) ``` @@ -241,7 +248,7 @@ Two packages are implicitly imported into the scope of all of your source code f - java.lang.* - scala.* -The Scala `Predef` object is also imported by default. +The members of the Scala object `Predef` are also imported by default. > If you ever wondered why you can use classes like `List`, `Vector`, `Map`, etc., without importing them, they’re available because of definitions in the `Predef` object. From 08ede3bd71d7e400206b247beaf213065bf2535d Mon Sep 17 00:00:00 2001 From: Todd O'Bryan Date: Mon, 14 Jun 2021 01:06:14 -0700 Subject: [PATCH 1506/3075] Update quotes.md (#2047) I think the first two things are just typos. The third seems much easier for me, as a native English speaker, to understand. --- _overviews/scala3-macros/tutorial/quotes.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/_overviews/scala3-macros/tutorial/quotes.md b/_overviews/scala3-macros/tutorial/quotes.md index fe99cb4260..a772b23f8f 100644 --- a/_overviews/scala3-macros/tutorial/quotes.md +++ b/_overviews/scala3-macros/tutorial/quotes.md @@ -14,7 +14,7 @@ Intuitively, the code directly within the quote is not executed now, while the c ```scala val msg = Expr("Hello") -val printHello = '{ print($hello) } +val printHello = '{ print($msg) } println(printHello.show) // print("Hello") ``` @@ -46,7 +46,8 @@ def myBadCounter2(using Quotes): Expr[Int] = '{ } ``` Clearly, this should not work as the variable does not exist yet. -To make sure you can only write programs that do not contain these kinds of problems we restrict the set of references to variable and other definitions. + +To make sure you cannot write programs that contain these kinds of problems, we restrict the kinds of references allowed in quote environments. We introduce _levels_ as a count of the number of quotes minus the number of splices surrounding an expression or definition. From e70abc8308d1d262ade788c96a11d27745815c02 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Wed, 2 Jun 2021 15:59:37 +0200 Subject: [PATCH 1507/3075] Some suggestions in the Scala 3 book --- _overviews/scala3-book/introduction.md | 4 +- _overviews/scala3-book/scala-features.md | 38 ++++----- _overviews/scala3-book/taste-collections.md | 12 ++- .../scala3-book/taste-control-structures.md | 17 ++-- _overviews/scala3-book/taste-functions.md | 4 +- _overviews/scala3-book/taste-methods.md | 2 +- _overviews/scala3-book/taste-modeling.md | 14 +-- _overviews/scala3-book/taste-objects.md | 4 +- _overviews/scala3-book/why-scala-3.md | 85 ++++++++++--------- scala3/contribute-to-docs.md | 2 +- 10 files changed, 90 insertions(+), 92 deletions(-) diff --git a/_overviews/scala3-book/introduction.md b/_overviews/scala3-book/introduction.md index c2e131e26c..3d3558203d 100644 --- a/_overviews/scala3-book/introduction.md +++ b/_overviews/scala3-book/introduction.md @@ -12,8 +12,8 @@ The goal of this book is to provide an informal introduction to the Scala langua It touches on all Scala topics, in a relatively light manner. If at any time while you’re reading this book and want more information on a specific feature, you’ll find links to our [_Reference_ documentation][reference], which covers many new features of the Scala language in more detail. -Over the course of this book, we hope to demonstrate that Scala is a beautiful, expressive programming language, with a clean, modern syntax, and supports functional programming (FP), object-oriented programming (OOP), and a fusion of FP and OOP in a typed setting. -Scala’s syntax, grammar, and features have been re-thought, debated in an open process, and updated in 2020 to be more clear and easier to understand than ever before. +Over the course of this book, we hope to demonstrate that Scala is a beautiful, expressive programming language, with a clean, modern syntax, which supports functional programming (FP) and object-oriented programming (OOP), and that provides a safe static type system. +Scala’s syntax, grammar, and features have been re-thought, debated in an open process, and updated in 2020 to be clearer and easier to understand than ever before. The book begins with a whirlwind tour of many of Scala’s features in the [“A Taste of Scala” section][taste]. After that tour, the sections that follow it provide more details on those language features. diff --git a/_overviews/scala3-book/scala-features.md b/_overviews/scala3-book/scala-features.md index 048d7e4519..f0c8efb129 100644 --- a/_overviews/scala3-book/scala-features.md +++ b/_overviews/scala3-book/scala-features.md @@ -30,8 +30,8 @@ Looking at Scala from the proverbial “30,000 foot view,” you can make the fo - It has a concise, readable syntax - It’s statically-typed (but feels dynamic) - It has an expressive type system -- It’s a pure functional programming (FP) language -- It’s a pure object-oriented programming (OOP) language +- It’s a functional programming (FP) language +- It’s an object-oriented programming (OOP) language - It supports the fusion of FP and OOP - Contextual abstractions provide a clear way to implement _term inference_ - It runs on the JVM (and in the browser) @@ -63,7 +63,7 @@ val newNumbers = double(oldNumbers) ``` That code instructs the compiler what to do on a step-by-step basis. -Instead, we write high-level, functional code using higher-order functions and lambdas like this to achieve the same effect: +Instead, we write high-level, functional code using higher-order functions and lambdas like this to compute the same result: ```scala val newNumbers = oldNumbers.map(_ * 2) @@ -92,7 +92,7 @@ nums.filter(i => i > 1) nums.filter(_ > 1) ``` -And traits, classes, and methods are defined with a clean, light syntax: +Traits, classes, and methods are defined with a clean, light syntax: ```scala trait Animal: @@ -128,15 +128,13 @@ As Heather Miller states, Scala is considered to be a [strong, statically-typed - Correctness: you catch most errors at compile-time - Great IDE support - - Code completion + - Reliable code completion - Catching errors at compile-time means catching mistakes as you type - Easy and reliable refactoring - - Reliable code completion - You can refactor your code with confidence - Method type declarations tell readers what the method does, and help serve as documentation -- Types make your code easier to maintain -- Scalability: types help ensure correctness across arbitrarily large applications and development teams -- Strong typing in combination with excellent inference enables mechanisms like [contextual abstraction]({{ site.scala3ref }}/contextual/motivation.html) that allows you to omit boilerplate code. Often, this boilerplate code can be inferred by the compiler, based on type definitions and a given context (e.g. method arguments for implicit parameters). +- Scalability and maintainability: types help ensure correctness across arbitrarily large applications and development teams +- Strong typing in combination with excellent inference enables mechanisms like [contextual abstraction]({{ site.scala3ref }}/contextual/motivation.html) that allows you to omit boilerplate code. Often, this boilerplate code can be inferred by the compiler, based on type definitions and a given context. {% comment %} In that list: @@ -156,11 +154,11 @@ In that list: - i removed these items until we can replace them: * [Compound types](/tour/compound-types.html) -* [Implicit parameters](/tour/implicit-parameters.html) and [conversions](/tour/implicit-conversions.html) +* [conversions](/tour/implicit-conversions.html) * [Explicitly typed self references](/tour/self-types.html) {% endcomment %} -Scala’s expressive type system enforces, at compile-time, that abstractions are used in a safe and coherent manner. +Scala’s type system enforces, at compile-time, that abstractions are used in a safe and coherent manner. In particular, the type system supports: - [Type inference](/tour/type-inference.html) @@ -187,11 +185,11 @@ In particular, the type system supports: In combination, these features provide a powerful basis for the safe reuse of programming abstractions and for the type-safe extension of software. -### A pure FP language +### A functional programming language Scala is a functional programming (FP) language, meaning: -- Functions are variables, and can be passed around like any other variable +- Functions are values, and can be passed around like any other value - Higher-order functions are directly supported - Lambdas are built in - Everything in Scala is an expression that returns a value @@ -200,10 +198,10 @@ Scala is a functional programming (FP) language, meaning: - Those collection classes come with dozens of functional methods: they don’t mutate the collection, but instead return an updated copy of the data -### A pure OOP language +### An object-oriented language -Scala is a _pure_ object-oriented programming (OOP) language. -Every variable is an object and every “operator” is a method. +Scala is an object-oriented programming (OOP) language. +Every value is an instance of a class and every “operator” is a method. In Scala, all types inherit from a top-level class `Any`, whose immediate children are `AnyVal` (_value types_, such as `Int` and `Boolean`) and `AnyRef` (_reference types_, as in Java). This means that the Java distinction between primitive types and boxed types (e.g. `int` vs. `Integer`) isn’t present in Scala. @@ -236,9 +234,9 @@ Following Haskell, Scala was the second popular language to have some form of _i In Scala 3 these concepts have been completely re-thought and more clearly implemented. The core idea is _term inference_: Given a type, the compiler synthesizes a “canonical” term that has that type. -In Scala, an implicit parameter directly leads to an inferred argument term that could also be written down explicitly. +In Scala, a context parameter directly leads to an inferred argument term that could also be written down explicitly. -Use cases for this concept include implementing type classes, establishing context, dependency injection, expressing capabilities, computing new types, and proving relationships between them. +Use cases for this concept include implementing [type classes]({% link _overviews/scala3-book/ca-type-classes.md %}), establishing context, dependency injection, expressing capabilities, computing new types, and proving relationships between them. Scala 3 makes this process more clear than ever before. Read about contextual abstractions in the [Reference documentation]({{ site.scala3ref }}/contextual/motivation.html). @@ -442,7 +440,7 @@ Serialization: - [ScalaPB](https://github.com/scalapb/ScalaPB) -Science and data analysis: +### Science and data analysis: - [Algebird](https://github.com/twitter/algebird) - [Spire](https://github.com/typelevel/spire) @@ -461,7 +459,7 @@ Science and data analysis: - [TensorFlow Scala](https://github.com/eaplatanios/tensorflow_scala) -### FP & FRP +### Functional Programming & Functional Reactive Programming FP: diff --git a/_overviews/scala3-book/taste-collections.md b/_overviews/scala3-book/taste-collections.md index e40b85887b..67fdbc1d61 100644 --- a/_overviews/scala3-book/taste-collections.md +++ b/_overviews/scala3-book/taste-collections.md @@ -60,15 +60,13 @@ nums.map(_.toUpperCase) // List("ONE", "TWO") nums.flatMap(_.toUpperCase) // List('O', 'N', 'E', 'T', 'W', 'O') ``` -These examples show how the “fold” and “reduce” methods are used to sum the values in a sequence of integers: +These examples show how the “foldLeft” and “reduceLeft” methods are used to sum the values in a sequence of integers: ```scala val firstTen = (1 to 10).toList // List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) -firstTen.reduce(_ + _) // 55 firstTen.reduceLeft(_ + _) // 55 -firstTen.fold(100)(_ + _) // 155 (100 is a “seed” value) -firstTen.foldLeft(100)(_ + _) // 155 +firstTen.foldLeft(100)(_ + _) // 155 (100 is a “seed” value) ``` There are many more methods available to Scala collections classes, and they’re demonstrated in the [Collections chapter][collections], and in the [API Documentation][api]. @@ -93,9 +91,9 @@ val t = (11, "eleven", Person("Eleven")) Once you have a tuple, you can access its values by binding them to variables, or access them by number: ```scala -t._1 // 11 -t._2 // "eleven" -t._3 // Person("Eleven") +t(0) // 11 +t(1) // "eleven" +t(2) // Person("Eleven") ``` You can also use this _extractor_ approach to assign the tuple fields to variable names: diff --git a/_overviews/scala3-book/taste-control-structures.md b/_overviews/scala3-book/taste-control-structures.md index a527f603d2..5c30f73da4 100644 --- a/_overviews/scala3-book/taste-control-structures.md +++ b/_overviews/scala3-book/taste-control-structures.md @@ -186,7 +186,7 @@ This example shows (a) how to use a `match` expression as the body of a method, ```scala // getClassAsString is a method that takes a single argument of any type. -def getClassAsString(x: Any): String = x match +def getClassAsString(x: Matchable): String = x match case s: String => s"'$s' is a String" case i: Int => "Int" case d: Double => "Double" @@ -199,6 +199,10 @@ getClassAsString("hello") // 'hello' is a String getClassAsString(List(1, 2, 3)) // List ``` +The method `getClassAsString` takes as a parameter a value of type [Matchable]({{ site.scala3ref }}/other-new-features/matchable.html), which can be +any type supporting pattern matching (some types don’t support pattern matching because this could +break encapsulation). + There’s _much_ more to pattern matching in Scala. Patterns can be nested, results of patterns can be bound, and pattern matching can even be user-defined. See the pattern matching examples in the [Control Structures chapter][control] for more details. @@ -231,29 +235,26 @@ It’s one-line syntax looks like this: while x >= 0 do x = f(x) ``` -Again, Scala’s control structure syntax is flexible, and you can write this code in different ways depending on your preferences: +In Scala 2, the syntax was a bit different. The condition was surrounded by parentheses, and +there was no `do` keyword: ```scala while (x >= 0) do x = f(x) while (x >= 0) { x = f(x) } ``` +Scala 3 still supports the Scala 2 syntax for the sake of compatibility. + The `while` loop multiline syntax looks like this: ```scala var x = 1 -// without parentheses while x < 3 do println(x) x += 1 - -// with parentheses -while (x < 3) - println(x) - x += 1 ``` diff --git a/_overviews/scala3-book/taste-functions.md b/_overviews/scala3-book/taste-functions.md index 7977f6d600..b103dba666 100644 --- a/_overviews/scala3-book/taste-functions.md +++ b/_overviews/scala3-book/taste-functions.md @@ -11,13 +11,13 @@ next-page: taste-objects Scala has most features you’d expect in a functional programming language, including: -- Lambdas +- Lambdas (anonymous functions) - Higher-order functions (HOFs) - Immutable collections in the standard library Lambdas, also known as _anonymous functions_, are a big part of keeping your code concise but readable. -The `map` method of the `List` class is a typical example of a higher-order function---a function that takes a lambda as parameter. +The `map` method of the `List` class is a typical example of a higher-order function---a function that takes a function as parameter. These two examples are equivalent, and show how to multiply each number in a list by `2` by passing a lambda into the `map` method: diff --git a/_overviews/scala3-book/taste-methods.md b/_overviews/scala3-book/taste-methods.md index 011ba23bd7..2718059bb1 100644 --- a/_overviews/scala3-book/taste-methods.md +++ b/_overviews/scala3-book/taste-methods.md @@ -128,7 +128,7 @@ extension (s: String) ## See also Scala Methods can be much more powerful: they can take type parameters and context parameters. -They are covered in detail in the [Data Modeling][data-1] section. +They are covered in detail in the [Domain Modeling][data-1] section. diff --git a/_overviews/scala3-book/taste-modeling.md b/_overviews/scala3-book/taste-modeling.md index aaee4fa19a..20c605c6f9 100644 --- a/_overviews/scala3-book/taste-modeling.md +++ b/_overviews/scala3-book/taste-modeling.md @@ -81,7 +81,7 @@ c.stopRunning() // "No need to stop" ``` If that code makes sense---great, you’re comfortable with traits as interfaces. -If not, don’t worry, they’re explained in more detail in the [Data Modeling][data-1] chapter. +If not, don’t worry, they’re explained in more detail in the [Domain Modeling][data-1] chapter. ### Classes @@ -106,7 +106,7 @@ Notice that the class declaration creates a constructor: val p = Person("John", "Stephens") ``` -Constructors and other class-related topics are covered in the [Data Modeling][data-1] chapter. +Constructors and other class-related topics are covered in the [Domain Modeling][data-1] chapter. ## FP Domain Modeling @@ -170,7 +170,7 @@ enum Nat: case Succ(pred: Nat) ``` -Enums are covered in detail in the [Data Modeling][data-1] section of this book, and in the [Reference documentation]({{ site.scala3ref }}/enums/enums.html). +Enums are covered in detail in the [Domain Modeling][data-1] section of this book, and in the [Reference documentation]({{ site.scala3ref }}/enums/enums.html). ### Case classes @@ -183,7 +183,7 @@ When the compiler sees the `case` keyword in front of a `class` it has these eff - An `unapply` method is generated, which lets you use case classes in more ways in `match` expressions. - A `copy` method is generated in the class. This provides a way to create updated copies of the object without changing the original object. -- `equals` and `hashCode` methods are generated. +- `equals` and `hashCode` methods are generated to implement structural equality. - A default `toString` method is generated, which is helpful for debugging. @@ -206,7 +206,7 @@ case class Person( val p = Person("Reginald Kenneth Dwight", "Singer") // a good default toString method -p // Person = Person(Reginald Kenneth Dwight,Singer) +p // : Person = Person(Reginald Kenneth Dwight,Singer) // can access its fields, which are immutable p.name // "Reginald Kenneth Dwight" @@ -215,10 +215,10 @@ p.name = "Joe" // error: can’t reassign a val field // when you need to make a change, use the `copy` method // to “update as you copy” val p2 = p.copy(name = "Elton John") -p2 // Person = Person(Elton John,Singer) +p2 // : Person = Person(Elton John,Singer) ``` -See the [Data Modeling][data-1] sections for many more details on `case` classes. +See the [Domain Modeling][data-1] sections for many more details on `case` classes. diff --git a/_overviews/scala3-book/taste-objects.md b/_overviews/scala3-book/taste-objects.md index 1ba49e30d6..ae522627f1 100644 --- a/_overviews/scala3-book/taste-objects.md +++ b/_overviews/scala3-book/taste-objects.md @@ -1,7 +1,7 @@ --- -title: Objects +title: Singleton Objects type: section -description: This section provides an introduction to the use of objects in Scala 3. +description: This section provides an introduction to the use of singleton objects in Scala 3. num: 12 previous-page: taste-functions next-page: taste-collections diff --git a/_overviews/scala3-book/why-scala-3.md b/_overviews/scala3-book/why-scala-3.md index e5f317f9f3..e6c5b2bd96 100644 --- a/_overviews/scala3-book/why-scala-3.md +++ b/_overviews/scala3-book/why-scala-3.md @@ -45,7 +45,7 @@ For instance, a `List` is defined as a class---technically it’s an abstract cl val x = List(1, 2, 3) ``` -However, what appears to the programmer to be a simple `List` is actually built from a combination of several specialized types, including an abstract class named `AbstractSeq`, traits like `LinearSeq` and `LinearSeqOps`, and more. +However, what appears to the programmer to be a simple `List` is actually built from a combination of several specialized types, including abstract classes named `Iterable`, `Seq`, and `LinearSeq`. Those types are similarly composed of other small, modular units of code. In addition to building a type like `List` from a series of modular traits, the `List` API also consists of dozens of other methods, many of which are higher-order functions: @@ -67,7 +67,7 @@ The `List` class is immutable, so all of those methods return new values, as sho ## 2) A dynamic feel Scala’s _type inference_ often makes the language feel dynamically typed, even though it’s statically typed. -This is true with variable assignment: +This is true with variable declaration: ```scala val a = 1 @@ -108,7 +108,7 @@ val b: Password | Username = if (true) name else password ## 3) Concise syntax -Scala is a low ceremony, “concise but still readable” language. For instance, variable type assignment is concise: +Scala is a low ceremony, “concise but still readable” language. For instance, variable declaration is concise: ```scala val a = 1 @@ -120,8 +120,8 @@ Creating types like traits, classes, and enumerations are concise: ```scala trait Tail: - def wagTail: Unit - def stopTail: Unit + def wagTail(): Unit + def stopTail(): Unit enum Topping: case Cheese, Pepperoni, Sausage, Mushrooms, Onions @@ -151,7 +151,7 @@ All of these expressions and many more are concise, and still very readable: wha Implicits in Scala 2 were a major distinguishing design feature. They represented _the_ fundamental way to abstract over context, with a unified paradigm that served a great variety of use cases, among them: -- Implementing type classes +- Implementing [type classes]({% link _overviews/scala3-book/ca-type-classes.md %}) - Establishing context - Dependency injection - Expressing capabilities @@ -208,7 +208,7 @@ See that chapter for more details on these features. Scala can be used on the server side with terrific frameworks: - The [Play Framework](https://www.playframework.com) lets you build highly scalable server-side applications and microservices -- [Akka Actors](https://akka.io) let you use the actor model to greatly simplify parallel and concurrent software applications +- [Akka Actors](https://akka.io) let you use the actor model to greatly simplify distributed and concurrent software applications Scala can also be used in the browser with the [Scala.js project](https://www.scala-js.org), which is a type-safe replacement for JavaScript. The Scala.js ecosystem [has dozens of libraries](https://www.scala-js.org/libraries) to let you use React, Angular, jQuery, and many other JavaScript and Scala libraries in the browser. @@ -227,50 +227,50 @@ While these all use the `List` class, the same methods work with other collectio Here are some examples: ```scala -List.range(1, 3) // List(1, 2) -List.range(1, 6, 2) // List(1, 3, 5) -List.fill(3)("foo") // List(foo, foo, foo) -List.tabulate(3)(n => n * n) // List(0, 1, 4) -List.tabulate(4)(n => n * n) // List(0, 1, 4, 9) - -val a = List(10, 20, 30, 40, 10) // List(10, 20, 30, 40, 10) -a.distinct // List(10, 20, 30, 40) -a.drop(2) // List(30, 40, 10) -a.dropRight(2) // List(10, 20, 30) -a.dropWhile(_ < 25) // List(30, 40, 10) -a.filter(_ < 25) // List(10, 20, 10) -a.filter(_ > 100) // List() -a.find(_ > 20) // Some(30) -a.head // 10 -a.headOption // Some(10) -a.init // List(10, 20, 30, 40) -a.intersect(List(19,20,21)) // List(20) -a.last // 10 -a.lastOption // Some(10) -a.map(_ * 2) // List(20, 40, 60, 80, 20) -a.slice(2,4) // List(30, 40) -a.tail // List(20, 30, 40, 10) -a.take(3) // List(10, 20, 30) -a.takeRight(2) // List(40, 10) -a.takeWhile(_ < 30) // List(10, 20) -a.filter(_ < 30).map(_ * 10) // List(100, 200) +List.range(1, 3) // List(1, 2) +List.range(start = 1, end = 6, step = 2) // List(1, 3, 5) +List.fill(3)("foo") // List(foo, foo, foo) +List.tabulate(3)(n => n * n) // List(0, 1, 4) +List.tabulate(4)(n => n * n) // List(0, 1, 4, 9) + +val a = List(10, 20, 30, 40, 10) // List(10, 20, 30, 40, 10) +a.distinct // List(10, 20, 30, 40) +a.drop(2) // List(30, 40, 10) +a.dropRight(2) // List(10, 20, 30) +a.dropWhile(_ < 25) // List(30, 40, 10) +a.filter(_ < 25) // List(10, 20, 10) +a.filter(_ > 100) // List() +a.find(_ > 20) // Some(30) +a.head // 10 +a.headOption // Some(10) +a.init // List(10, 20, 30, 40) +a.intersect(List(19,20,21)) // List(20) +a.last // 10 +a.lastOption // Some(10) +a.map(_ * 2) // List(20, 40, 60, 80, 20) +a.slice(2, 4) // List(30, 40) +a.tail // List(20, 30, 40, 10) +a.take(3) // List(10, 20, 30) +a.takeRight(2) // List(40, 10) +a.takeWhile(_ < 30) // List(10, 20) +a.filter(_ < 30).map(_ * 10) // List(100, 200) val fruits = List("apple", "pear") -fruits.map(_.toUpperCase) // List(APPLE, PEAR) -fruits.flatMap(_.toUpperCase) // List(A, P, P, L, E, P, E, A, R) +fruits.map(_.toUpperCase) // List(APPLE, PEAR) +fruits.flatMap(_.toUpperCase) // List(A, P, P, L, E, P, E, A, R) val nums = List(10, 5, 8, 1, 7) -nums.sorted // List(1, 5, 7, 8, 10) -nums.sortWith(_ < _) // List(1, 5, 7, 8, 10) -nums.sortWith(_ > _) // List(10, 8, 7, 5, 1) +nums.sorted // List(1, 5, 7, 8, 10) +nums.sortWith(_ < _) // List(1, 5, 7, 8, 10) +nums.sortWith(_ > _) // List(10, 8, 7, 5, 1) ``` -## 8) Built-in practices +## 8) Built-in best practices Scala idioms encourage best practices in many ways. -For immutability, you’re encouraged to create immutable `val` fields: +For immutability, you’re encouraged to create immutable `val` declarations: ```scala val a = 1 // immutable variable @@ -283,7 +283,7 @@ val b = List(1,2,3) // List is immutable val c = Map(1 -> "one") // Map is immutable ``` -Case classes are primarily intended for use in functional programming, and their parameters are immutable: +Case classes are primarily intended for use in [domain modeling]({% link _overviews/scala3-book/domain-modeling-intro.md %}), and their parameters are immutable: ```scala case class Person(name: String) @@ -386,6 +386,7 @@ _Safety_ is related to several new and changed features: - Multiversal equality - Restricting implicit conversions - Null safety +- Safe initialization Good examples of _ergonomics_ are enumerations and extension methods, which have been added to Scala 3 in a very readable manner: diff --git a/scala3/contribute-to-docs.md b/scala3/contribute-to-docs.md index 91b467766f..642a12f2c0 100644 --- a/scala3/contribute-to-docs.md +++ b/scala3/contribute-to-docs.md @@ -16,7 +16,7 @@ We welcome contributions from the community to every aspect of the documentation ### How can I contribute? -In general, there is many different ways you could help us: +In general, there are many ways you can help us: - **Confused about something in any of the docs?** Open an issue. - **Found something not up-to-date?** Open an issue or create a PR. From 5bc689d64915c1e7f90a6d821e2adc7aa3c36a47 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Mon, 7 Jun 2021 18:35:57 +0200 Subject: [PATCH 1508/3075] Some suggestions in the Scala 3 book (2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I’ve reviewed the following chapters: - a first look at types - control structures - domain modeling Here are some simple suggestions, or typos fixes. --- _overviews/scala3-book/control-structures.md | 34 ++++++------------- _overviews/scala3-book/domain-modeling-fp.md | 2 +- _overviews/scala3-book/domain-modeling-oop.md | 21 ++++++------ .../scala3-book/domain-modeling-tools.md | 20 +---------- _overviews/scala3-book/first-look-at-types.md | 7 ++-- 5 files changed, 27 insertions(+), 57 deletions(-) diff --git a/_overviews/scala3-book/control-structures.md b/_overviews/scala3-book/control-structures.md index a1fd727a3d..50f81a2b1b 100644 --- a/_overviews/scala3-book/control-structures.md +++ b/_overviews/scala3-book/control-structures.md @@ -144,26 +144,14 @@ scala> for i <- ints do println(i) 3 ```` -When you need a multiline block of code following the `for` generator, use either of these approaches: +When you need a multiline block of code following the `for` generator, use the following syntax: ```scala -// option 1 for i <- ints do val x = i * 2 println(s"i = $i, x = $x") - -// option 2 -for (i <- ints) - val x = i * 2 - println(s"i = $i, x = $x") - -// option 3 -for (i <- ints) { - val x = i * 2 - println(s"i = $i, x = $x") -} ``` ### Multiple generators @@ -276,7 +264,7 @@ val list = yield i * 2 -// result: list == Vector(20, 22, 24) +// list: IndexedSeq[Int] = Vector(20, 22, 24) ``` After that `for` expression runs, the variable `list` is a `Vector` that contains the values shown. @@ -288,7 +276,7 @@ This is how the expression works: It multiples it by `2`, then yields the value `22`. You can think of these yielded values as accumulating in a temporary holding place. 3. Finally the loop gets the number `12` from the range, multiplies it by `2`, yielding the number `24`. - The loop completes at this point and yields the final result, the `Vector(20,22,24)`. + The loop completes at this point and yields the final result, the `Vector(20, 22, 24)`. {% comment %} NOTE: This is a place where it would be great to have a TIP or NOTE block: @@ -297,7 +285,7 @@ NOTE: This is a place where it would be great to have a TIP or NOTE block: While the intent of this section is to demonstrate `for` expressions, it can help to know that the `for` expression shown is equivalent to this `map` method call: ```scala -val list = (10 to 12).map { i => i * 2} +val list = (10 to 12).map(i => i * 2) ``` `for` expressions can be used any time you need to traverse all of the elements in a collection and apply an algorithm to those elements to create a new list. @@ -312,7 +300,7 @@ val capNames = for name <- names yield val capName = nameWithoutUnderscore.capitalize capName -// result: List[String] = List(Olivia, Walter, Peter) +// capNames: List[String] = List(Olivia, Walter, Peter) ``` @@ -329,7 +317,7 @@ def between3and10(xs: List[Int]): List[Int] = if x <= 10 yield x -between3and10(List(1, 3, 7, 11)) // result: List(3, 7) +between3and10(List(1, 3, 7, 11)) // : List[Int] = List(3, 7) ``` @@ -386,7 +374,7 @@ If it’s between `0` and `6`, `day` is bound to a string that represents one of Otherwise, the catch-all case is represented by the `_` character, and `day` is bound to the string, `"invalid day"`. > When writing simple `match` expressions like this, it’s recommended to use the `@switch` annotation on the variable `i`. -> This annotation provides a compile time warning if the switch can’t be compiled to a `tableswitch` or `lookupswitch`, which are better for performance. +> This annotation provides a compile-time warning if the switch can’t be compiled to a `tableswitch` or `lookupswitch`, which are better for performance. ### Using the default value @@ -417,7 +405,7 @@ val evenOrOdd = i match ``` -### Using `if` expressions in `case` statements +### Using `if` guards in `case` clauses You can also use guards in the `case`s of a match expression. In this example the second and third `case` both use guards to match multiple integer values: @@ -528,8 +516,8 @@ def pattern(x: Matchable): String = x match case a: Array[Int] => s"array of int: ${a.mkString(",")}" case as: Array[String] => s"string array: ${as.mkString(",")}" case d: Dog => s"dog: ${d.name}" - case list: List[_] => s"got a List: $list" - case m: Map[_, _] => m.toString + case list: List[?] => s"got a List: $list" + case m: Map[?, ?] => m.toString // the default wildcard pattern case _ => "Unknown" @@ -561,7 +549,7 @@ finally println("Came to the 'finally' clause.") ``` -Assuming that the `openAndReadAFile` method uses the Java `java.io._` classes to read a file and doesn’t catch its exceptions, attempting to open and read a file can result in both a `FileNotFoundException` and an `IOException`, and those two exceptions are caught in the `catch` block of this example. +Assuming that the `openAndReadAFile` method uses the Java `java.io.*` classes to read a file and doesn’t catch its exceptions, attempting to open and read a file can result in both a `FileNotFoundException` and an `IOException`, and those two exceptions are caught in the `catch` block of this example. [matchable]: {{ site.scala3ref }}/other-new-features/matchable.html diff --git a/_overviews/scala3-book/domain-modeling-fp.md b/_overviews/scala3-book/domain-modeling-fp.md index 4d42dc6abb..dec7dda6d2 100644 --- a/_overviews/scala3-book/domain-modeling-fp.md +++ b/_overviews/scala3-book/domain-modeling-fp.md @@ -43,7 +43,7 @@ An FP design is implemented in a similar way: > As we will see, reasoning about programs in this style is quite different from the object-oriented programming. > Data in FP simply **is**: -> Separating functionality from your data let's you inspect your data without having to worry about behavior. +> Separating functionality from your data lets you inspect your data without having to worry about behavior. In this chapter we’ll model the data and operations for a “pizza” in a pizza store. You’ll see how to implement the “data” portion of the Scala/FP model, and then you’ll see several different ways you can organize the operations on that data. diff --git a/_overviews/scala3-book/domain-modeling-oop.md b/_overviews/scala3-book/domain-modeling-oop.md index 10821996d9..c06260d84d 100644 --- a/_overviews/scala3-book/domain-modeling-oop.md +++ b/_overviews/scala3-book/domain-modeling-oop.md @@ -89,12 +89,11 @@ When designing software in Scala, it’s often helpful to only consider using cl NOTE: I think “leaves” may technically be the correct word to use, but I prefer “leafs.” {% endcomment %} -```text -traits T1 T2 ... T3 -composed traits S extends T1, T2 ... S extends T2, T3 -classes C extends S, T3 -instances new C -``` +| Traits | `T1`, `T2`, `T3` +| Composed traits | `S extends T1, T2`, `S extends T2, T3` +| Classes | `C extends S, T3` +| Instances | `C()` + This is even more the case in Scala 3, where traits now can also take parameters, further eliminating the need for classes. #### Defining Classes @@ -147,7 +146,7 @@ class Counter: // can only be observed by the method `count` private var currentCount = 0 - def tick() = currentCount += 1 + def tick(): Unit = currentCount += 1 def count: Int = currentCount ``` Every instance of the class `Counter` has its own private state that can only be observed through the method `count`, as the following interaction illustrates: @@ -198,7 +197,7 @@ There are a few things that need explanation. #### Abstract Type Members The declaration `type S <: Subject` says that within the trait `SubjectObserver` we can refer to some _unknown_ (that is, abstract) type that we call `S`. However, the type is not completely unknown: we know at least that it is _some subtype_ of the trait `Subject`. -All traits and classes extending `SubjectObserer` are free to chose any type for `S` as long as the chosen type is a subtype of `Subject`. +All traits and classes extending `SubjectObserer` are free to choose any type for `S` as long as the chosen type is a subtype of `Subject`. The `<: Subject` part of the declaration is also referred to as an _upper bound on `S`_. #### Nested Traits @@ -210,12 +209,12 @@ The second trait, `Subject`, defines one private field `observers` to store all Subscribing to a subject simply stores the object into this list. Again, the type of parameter `obs` is `O`, not `Observer`. -#### Selftype Annotations +#### Self-type Annotations Finally, you might have wondered what the `self: S =>` on trait `Subject` is supposed to mean. -This is called a _selftype annotation_. +This is called a _self-type annotation_. It requires subtypes of `Subject` to also be subtypes of `S`. This is necessary to be able to call `obs.notify` with `this` as an argument, since it requires a value of type `S`. -If `S` was a _concrete_ type, the selftype annotation could be replaced by `trait Subject extends S`. +If `S` was a _concrete_ type, the self-type annotation could be replaced by `trait Subject extends S`. ### Implementing the Component We can now implement the above component and define the abstract type members to be concrete types: diff --git a/_overviews/scala3-book/domain-modeling-tools.md b/_overviews/scala3-book/domain-modeling-tools.md index bd9e955ba5..b8fd76f2fc 100644 --- a/_overviews/scala3-book/domain-modeling-tools.md +++ b/_overviews/scala3-book/domain-modeling-tools.md @@ -33,27 +33,9 @@ class Movie(var name: String, var director: String, var year: Int) ``` These examples show that Scala has a very lightweight way to declare classes. -The definition of the class `Person` roughly corresponds to the following, more explicit, version: - -```scala -class Person: - // fields - var name: String = null - var vocation: String = null - - // constructor - def this(_name: String, _vocation: String) = - // call to the super constructor - this() - // assigning the fields - name = _name - vocation = _vocation -``` - -This version defines the two fields `name` and `vocation`, together with a constructor that accepts values for those two fields and assigns them. All of the parameters of our example classes are defined as `var` fields, which means they are mutable: you can read them, and also modify them. -If you want them to be immutable---read only---create them as `val` fields instead. +If you want them to be immutable---read only---create them as `val` fields instead, or use a case class. Prior to Scala 3, you used the `new` keyword to create a new instance of a class: diff --git a/_overviews/scala3-book/first-look-at-types.md b/_overviews/scala3-book/first-look-at-types.md index 0a14e41a8c..106f564258 100644 --- a/_overviews/scala3-book/first-look-at-types.md +++ b/_overviews/scala3-book/first-look-at-types.md @@ -267,13 +267,14 @@ A common use is to signal non-termination, such as a thrown exception, program e `Null` is a subtype of all reference types (i.e. any subtype of `AnyRef`). It has a single value identified by the keyword literal `null`. -`Null` is provided mostly for interoperability with other JVM languages and should almost never be used in Scala code. -Alternatives to `null` are discussed in the [Functional Programming chapter][fp] of this book, and the [API documentation][option-api]. - +Currently, the usage of `null` is considered bad practice. It should be used mostly for interoperability with other JVM languages. An opt-in compiler option changes the status of `Null` to fix the caveats related to its usage. This option might become the default in a future version of Scala. You can learn more about it [here][safe-null]. +In the meantime, `null` should almost never be used in Scala code. +Alternatives to `null` are discussed in the [Functional Programming chapter][fp] of this book, and the [API documentation][option-api]. [reference]: {{ site.scala3ref }}/overview.html [matchable]: {{ site.scala3ref }}/other-new-features/matchable.html [interpolation]: {% link _overviews/core/string-interpolation.md %} [fp]: {% link _overviews/scala3-book/fp-intro.md %} [option-api]: https://dotty.epfl.ch/api/scala/Option.html +[safe-null]: {{ site.scala3ref }}/other-new-features/explicit-nulls.html From 84ef96cf45c0c27a59fda3162b529e01d210f6c8 Mon Sep 17 00:00:00 2001 From: SourceCodeBot Date: Mon, 14 Jun 2021 21:14:46 +0200 Subject: [PATCH 1509/3075] fix: fix syntax issue with arguments --- _overviews/scala3-book/ca-given-using-clauses.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-book/ca-given-using-clauses.md b/_overviews/scala3-book/ca-given-using-clauses.md index dd1b4ccc1b..5ba38fd64b 100644 --- a/_overviews/scala3-book/ca-given-using-clauses.md +++ b/_overviews/scala3-book/ca-given-using-clauses.md @@ -26,7 +26,7 @@ def renderWebsite(path: String, c: Config): String = def renderWidget(items: List[String], c: Config): String = ??? val config = Config(8080, "docs.scala-lang.org") -renderWebsite("/home")(config) +renderWebsite("/home", config) ``` Let us assume that the configuration does not change throughout most of our code base. Passing `c` to each and every method call (like `renderWidget`) becomes very tedious and makes our program more difficult to read, since we need to ignore the `c` argument. From 83206c35bbfeaafe52ae49bd92d709894e76d1f3 Mon Sep 17 00:00:00 2001 From: Stephan Schneider Date: Mon, 14 Jun 2021 21:32:28 +0200 Subject: [PATCH 1510/3075] Update index.md typo --- _overviews/FAQ/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/FAQ/index.md b/_overviews/FAQ/index.md index 0e4b7200ad..e7d25dbcf5 100644 --- a/_overviews/FAQ/index.md +++ b/_overviews/FAQ/index.md @@ -188,7 +188,7 @@ differ from a function value such as: Note that in **Scala 3** most of the differences will go; for example, they will be able to [accept implicit parameters](https://dotty.epfl.ch/docs/reference/contextual/context-functions.html) -as well as [type parameterts](https://dotty.epfl.ch/docs/reference/new-types/polymorphic-function-types.html). +as well as [type parameters](https://dotty.epfl.ch/docs/reference/new-types/polymorphic-function-types.html). Nevertheless, it is still recommended to use methods most of the time, unless you absolutely need a function. And, thanks to From f6943140ff557f826c81e2d46ea96d72f6a83011 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Mon, 14 Jun 2021 17:04:36 +0200 Subject: [PATCH 1511/3075] Suggestions in the Scala 3 book (part 4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I’ve reviewed the following chapters: - Scala Collections - Functional Programming - Types and the Type System - Contextual Abstractions --- _overviews/scala3-book/ca-context-bounds.md | 2 +- .../scala3-book/ca-given-using-clauses.md | 2 +- .../scala3-book/ca-implicit-conversions.md | 11 +++--- _overviews/scala3-book/collections-classes.md | 36 ++++++++++--------- _overviews/scala3-book/collections-methods.md | 16 ++++----- .../fp-functional-error-handling.md | 18 +++++----- _overviews/scala3-book/types-inferred.md | 2 +- _overviews/scala3-book/types-type-classes.md | 4 +-- _overviews/scala3-book/types-variance.md | 16 ++++----- 9 files changed, 57 insertions(+), 50 deletions(-) diff --git a/_overviews/scala3-book/ca-context-bounds.md b/_overviews/scala3-book/ca-context-bounds.md index fd435eb68f..462774a2d4 100644 --- a/_overviews/scala3-book/ca-context-bounds.md +++ b/_overviews/scala3-book/ca-context-bounds.md @@ -13,7 +13,7 @@ next-page: ca-given-imports - TODO: define "synthesized" and "synthesized arguments" {% endcomment %} -In many situations the name of a _context parameter_ doesn’t have to be mentioned explicitly, since it’s only used in synthesized arguments for other context parameters. +In many situations the name of a _context parameter_ doesn’t have to be mentioned explicitly, since it’s only used by the compiler in synthesized arguments for other context parameters. In that case you don’t have to define a parameter name, and can just provide the parameter type. diff --git a/_overviews/scala3-book/ca-given-using-clauses.md b/_overviews/scala3-book/ca-given-using-clauses.md index dd1b4ccc1b..39af385316 100644 --- a/_overviews/scala3-book/ca-given-using-clauses.md +++ b/_overviews/scala3-book/ca-given-using-clauses.md @@ -47,7 +47,7 @@ The Scala compiler thus performs **term inference**. In our call to `renderWidget(List("cart"))` the Scala compiler will see that there is a term of type `Config` in scope (the `c`) and automatically provide it to `renderWidget`. So the program is equivalent to the one above. -In fact, since we do not need to refer to `c` in our implementation of `renderWebsite` anymore, we can even omit it in the signature: +In fact, since we do not need to refer to `c` in our implementation of `renderWebsite` anymore, we can even omit its name in the signature: ```scala // no need to come up with a parameter name diff --git a/_overviews/scala3-book/ca-implicit-conversions.md b/_overviews/scala3-book/ca-implicit-conversions.md index 4a421da97b..d04cefa104 100644 --- a/_overviews/scala3-book/ca-implicit-conversions.md +++ b/_overviews/scala3-book/ca-implicit-conversions.md @@ -8,8 +8,8 @@ next-page: ca-summary --- -Implicit conversions are defined by `given` instances of the _scala.Conversion_ class. -For example, not accounting for possible conversion errors, this code defines an an implicit conversion from `String` to `Int`: +Implicit conversions are defined by `given` instances of the `scala.Conversion` class. +For example, not accounting for possible conversion errors, this code defines an implicit conversion from `String` to `Int`: ```scala given Conversion[String, Int] with @@ -34,10 +34,13 @@ def plus1(i: Int) = i + 1 plus1("1") ``` +> Note the clause `import scala.language.implicitConversions` at the beginning, +> to enable implicit conversions in the file. + ## Discussion -The Predef package contains “auto-boxing” conversions that map primitive number types to subclasses of _java.lang.Number_. -For instance, the conversion from `Int` to _java.lang.Integer_ can be defined as follows: +The Predef package contains “auto-boxing” conversions that map primitive number types to subclasses of `java.lang.Number`. +For instance, the conversion from `Int` to `java.lang.Integer` can be defined as follows: ```scala given int2Integer: Conversion[Int, java.lang.Integer] = diff --git a/_overviews/scala3-book/collections-classes.md b/_overviews/scala3-book/collections-classes.md index 7226398406..e9b7adec45 100644 --- a/_overviews/scala3-book/collections-classes.md +++ b/_overviews/scala3-book/collections-classes.md @@ -28,9 +28,9 @@ When you need more flexibility, see these pages at the end of this section for m Looking at Scala collections from a high level, there are three main categories to choose from: -- **Sequences** are a linear collection of elements and may be _indexed_ (like an array) or _linear_ (like a linked list) +- **Sequences** are a sequential collection of elements and may be _indexed_ (like an array) or _linear_ (like a linked list) - **Maps** contain a collection of key/value pairs, like a Java `Map`, Python dictionary, or Ruby `Hash` -- **Sets** are an unordered sequence of unique elements +- **Sets** are an unordered collection of unique elements All of those are basic types, and have subtypes for specific purposes, such as concurrency, caching, and streaming. In addition to those three main categories, there are other useful collection types, including ranges, stacks, and queues. @@ -74,7 +74,7 @@ The main collections you’ll use on a regular basis are: | `LazyList` | ✓ | | A lazy immutable linked list, its elements are computed only when they’re needed; Good for large or infinite sequences. | | `ArrayBuffer` | | ✓ | The go-to type for a mutable, indexed sequence | | `ListBuffer` | | ✓ | Used when you want a mutable `List`; typically converted to a `List` | -| `Map` | ✓ | ✓ | An iterable sequence that consists of pairs of keys and values. | +| `Map` | ✓ | ✓ | An iterable collection that consists of pairs of keys and values. | | `Set` | ✓ | ✓ | An iterable collection with no duplicate elements | As shown, `Map` and `Set` come in both immutable and mutable versions. @@ -109,7 +109,7 @@ For example, if you need an immutable, indexed collection, in general you should Conversely, if you need a mutable, indexed collection, use an `ArrayBuffer`. > `List` and `Vector` are often used when writing code in a functional style. -> `ArrayBuffer` is commonly used when writing code in a mutable style. +> `ArrayBuffer` is commonly used when writing code in an imperative style. > `ListBuffer` is used when you’re mixing styles, such as building a list. The next several sections briefly demonstrate the `List`, `Vector`, and `ArrayBuffer` types. @@ -291,7 +291,7 @@ val nums = Vector(1, 2, 3, 4, 5) val strings = Vector("one", "two") -case class Person(val name: String) +case class Person(name: String) val people = Vector( Person("Bert"), Person("Ernie"), @@ -383,10 +383,9 @@ Or if you prefer methods with textual names you can also use `append`, `appendAl Here are some examples of `+=` and `++=`: ```scala -var nums = ArrayBuffer(1, 2, 3) // ArrayBuffer(1, 2, 3) +val nums = ArrayBuffer(1, 2, 3) // ArrayBuffer(1, 2, 3) nums += 4 // ArrayBuffer(1, 2, 3, 4) -nums += (5, 6) // ArrayBuffer(1, 2, 3, 4, 5, 6) -nums ++= List(7, 8) // ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8) +nums ++= List(5, 6) // ArrayBuffer(1, 2, 3, 4, 5, 6) ``` ### Removing elements from an ArrayBuffer @@ -415,7 +414,7 @@ a.update(0, 10) // ArrayBuffer(10, 2, 50, 4) ## Maps -A `Map` is an iterable sequence that consists of pairs of keys and values. +A `Map` is an iterable collection that consists of pairs of keys and values. Scala has both mutable and immutable `Map` types, and this section demonstrates how to use the _immutable_ `Map`. ### Creating an immutable Map @@ -433,13 +432,13 @@ val states = Map( Once you have a `Map` you can traverse its elements in a `for` loop like this: ```scala -for ((k,v) <- states) println(s"key: $k, value: $v") +for (k, v) <- states do println(s"key: $k, value: $v") ``` The REPL shows how this works: ```` -scala> for ((k,v) <- states) println(s"key: $k, value: $v") +scala> for (k, v) <- states do println(s"key: $k, value: $v") key: AK, value: Alaska key: AL, value: Alabama key: AZ, value: Arizona @@ -463,7 +462,7 @@ Add elements to an immutable map using `+` and `++`, remembering to assign the r ```scala val a = Map(1 -> "one") // a: Map(1 -> one) val b = a + (2 -> "two") // b: Map(1 -> one, 2 -> two) -val c = b + ( +val c = b ++ Seq( 3 -> "three", 4 -> "four" ) @@ -482,13 +481,13 @@ val a = Map( 4 -> "four" ) -a - 4 // Map(1 -> one, 2 -> two, 3 -> three) -a - 4 - 3 // Map(1 -> one, 2 -> two) +val b = a - 4 // b: Map(1 -> one, 2 -> two, 3 -> three) +val c = a - 4 - 3 // c: Map(1 -> one, 2 -> two) ``` ### Updating Map elements -To update elements in an immutable map, use the `updated` method while assigning the result to a new variable: +To update elements in an immutable map, use the `updated` method (or the `+` operator) while assigning the result to a new variable: ```scala val a = Map( @@ -497,7 +496,8 @@ val a = Map( 3 -> "three" ) -val b = a.updated(3, "THREE!") // Map(1 -> one, 2 -> two, 3 -> THREE!) +val b = a.updated(3, "THREE!") // b: Map(1 -> one, 2 -> two, 3 -> THREE!) +val c = a + (2 -> "TWO...") // c: Map(1 -> one, 2 -> TWO..., 3 -> three) ``` ### Traversing a Map @@ -511,7 +511,7 @@ val states = Map( "AZ" -> "Arizona" ) -for ((k,v) <- states) println(s"key: $k, value: $v") +for (k, v) <- states do println(s"key: $k, value: $v") ``` That being said, there are _many_ ways to work with the keys and values in a map. @@ -558,6 +558,8 @@ val c = b ++ Seq(4, 1, 5, 5) // HashSet(5, 1, 2, 3, 4) Notice that when you attempt to add duplicate elements, they’re quietly dropped. +Also notice that the order of iteration of the elements is arbitrary. + ### Deleting elements from a Set diff --git a/_overviews/scala3-book/collections-methods.md b/_overviews/scala3-book/collections-methods.md index 3e6c208a21..4316dea761 100644 --- a/_overviews/scala3-book/collections-methods.md +++ b/_overviews/scala3-book/collections-methods.md @@ -34,7 +34,7 @@ The following methods work on all of the sequence types, including `List`, `Vect ## Examples of common methods To give you an overview of what you’ll see in the following sections, these examples show some of the most commonly used collections methods. -First, here are some methods don’t use lambdas: +First, here are some methods that don’t use lambdas: ```scala val a = List(10, 20, 30, 40, 10) // List(10, 20, 30, 40, 10) @@ -103,7 +103,7 @@ a.map(double(_)) a.map(double) ``` -In the last example, when an anonymous function consists of one statement that takes a single argument, you don’t have to name the argument, so even `-` isn’t required. +In the last example, when an anonymous function consists of one function call that takes a single argument, you don’t have to name the argument, so even `_` isn’t required. Finally, you can combine HOFs as desired to solve problems: @@ -217,10 +217,10 @@ david ## `head` The `head` method comes from Lisp and other earlier functional programming languages. -It’s used to print the first element (the head element) of a list: +It’s used to access the first element (the head element) of a list: ```scala -oneToTen.head // Int = 1 +oneToTen.head // 1 names.head // adam ``` @@ -228,8 +228,8 @@ Because a `String` can be seen as a sequence of characters, you can also treat i This is how `head` works on these strings: ```scala -"foo".head // Char = 'f' -"bar".head // Char = 'b' +"foo".head // 'f' +"bar".head // 'b' ``` `head` is a great method to work with, but as a word of caution it can also throw an exception when called on an empty collection: @@ -242,7 +242,7 @@ emptyList.head // java.util.NoSuchElementException: head of empty Because of this you may want to use `headOption` instead of `head`, especially when programming in a functional style: ```scala -emptyList.headOption // Option[Int] = None +emptyList.headOption // None ``` As shown, it doesn’t throw an exception, it simply returns the type `Option` that has the value `None`. @@ -256,7 +256,7 @@ The `tail` method also comes from Lisp, and it’s used to print every element i A few examples demonstrate this: ```scala -oneToTen.head // Int = 1 +oneToTen.head // 1 oneToTen.tail // List(2, 3, 4, 5, 6, 7, 8, 9, 10) names.head // adam diff --git a/_overviews/scala3-book/fp-functional-error-handling.md b/_overviews/scala3-book/fp-functional-error-handling.md index ee33cffe11..d56dfff3a6 100644 --- a/_overviews/scala3-book/fp-functional-error-handling.md +++ b/_overviews/scala3-book/fp-functional-error-handling.md @@ -106,7 +106,7 @@ makeInt(x) match case None => println("That didn’t work.") ``` -In this example, if `x` can be converted to an `Int`, the first `case` statement is executed; if `x` can’t be converted to an `Int`, the second `case` statement is executed. +In this example, if `x` can be converted to an `Int`, the expression on the right-hand side of the first `case` clause is evaluated; if `x` can’t be converted to an `Int`, the expression on the right-hand side of the second `case` clause is evaluated. @@ -240,19 +240,20 @@ makeInt(x) match Getting back to `null` values, a place where a `null` value can silently creep into your code is with a class like this: ```scala -class Address: +class Address( var street1: String, var street2: String, - var city: String, - var state: String, + var city: String, + var state: String, var zip: String +) ``` While every address on Earth has a `street1` value, the `street2` value is optional. As a result, the `street2` field can be assigned a `null` value: ```scala -val santa = new Address( +val santa = Address( "1 Main Street", null, // <-- D’oh! A null value! "North Pole", @@ -265,18 +266,19 @@ Historically, developers have used blank strings and null values in this situati In Scala---and other modern languages---the correct solution is to declare up front that `street2` is optional: ```scala -class Address: +class Address( var street1: String, var street2: Option[String], // an optional value var city: String, var state: String, var zip: String +) ``` Now developers can write more accurate code like this: ```scala -val santa = new Address( +val santa = Address( "1 Main Street", None, // 'street2' has no value "North Pole", @@ -288,7 +290,7 @@ val santa = new Address( or this: ```scala -val santa = new Address( +val santa = Address( "123 Main Street", Some("Apt. 2B"), "Talkeetna", diff --git a/_overviews/scala3-book/types-inferred.md b/_overviews/scala3-book/types-inferred.md index fab485fecc..d56bafb629 100644 --- a/_overviews/scala3-book/types-inferred.md +++ b/_overviews/scala3-book/types-inferred.md @@ -12,7 +12,7 @@ As with other statically typed programming languages, in Scala you can _declare_ ```scala val x: Int = 1 -val x: Double = 1 +val y: Double = 1 ``` In those examples the types are _explicitly_ declared to be `Int` and `Double`, respectively. diff --git a/_overviews/scala3-book/types-type-classes.md b/_overviews/scala3-book/types-type-classes.md index 239866ecb7..24619309d1 100644 --- a/_overviews/scala3-book/types-type-classes.md +++ b/_overviews/scala3-book/types-type-classes.md @@ -23,7 +23,7 @@ In Scala 3, _type classes_ are just _traits_ with one or more type parameters, l trait Show[A]: def show(a: A): String ``` -Instances of `Show` for a particular type `A` witness that `A` we can show an instance of type `A`. +Instances of `Show` for a particular type `A` witness that we can show (i.e., produce a text representation of) an instance of type `A`. For example, let’s look at the following `Show` instance for `Int` values: ```scala @@ -43,7 +43,7 @@ toHtml(42)(ShowInt()) // results in "

The number is 42!

" ``` -#### Automatically passing Type Class Instances +#### Automatically passing type class instances Since type classes are a very important way to structure software, Scala 3 offers additional features that make working with them very convenient. We discuss these additional features (which fall into the category of *Contextual Abstractions*) in a [later chapter][typeclasses-chapter] of this book. diff --git a/_overviews/scala3-book/types-variance.md b/_overviews/scala3-book/types-variance.md index 5eec37b647..90ee0d04ba 100644 --- a/_overviews/scala3-book/types-variance.md +++ b/_overviews/scala3-book/types-variance.md @@ -22,11 +22,11 @@ Let us also assume the following parameterized types: trait Pipeline[T]: def process(t: T): T -// an example of an covariant type +// an example of a covariant type trait Producer[+T]: def make: T -// an example of an contravariant type +// an example of a contravariant type trait Consumer[-T]: def take(t: T): Unit ``` @@ -73,7 +73,7 @@ In contrast to `Pipeline`, which is invariant, the type `Producer` is marked as This is valid, since the type parameter is only used in a _return position_. Marking it as covariant means that we can pass (or return) a `Producer[Book]` where a `Producer[Buyable]` is expected. -And in fact, this is sound: The type of `Producer[Buyable].make` only promises to _return_ a `Buyable`. +And in fact, this is sound. The type of `Producer[Buyable].make` only promises to _return_ a `Buyable`. As a caller of `make`, we will be happy to also accept a `Book`, which is a subtype of `Buyable`---that is, it is _at least_ a `Buyable`. This is illustrated by the following example, where the function `makeTwo` expects a `Producer[Buyable]`: @@ -108,12 +108,12 @@ They have an additional ISBN method in our example, but you are free to ignore t In contrast to the type `Producer`, which is marked as covariant, the type `Consumer` is marked as **contravariant** by prefixing the type parameter with a `-`. This is valid, since the type parameter is only used in an _argument position_. -Marking it as contravariant means that we can pass (or return) a `Producer[Item]` where a `Producer[Buyable]` is expected. -That is, we have the subtyping relationship `Producer[Item] <: Producer[Buyable]`. -Remember, for type `Consumer`, it was the other way around, and we had `Consumer[Buyable] <: Consumer[Item]`. +Marking it as contravariant means that we can pass (or return) a `Consumer[Item]` where a `Consumer[Buyable]` is expected. +That is, we have the subtyping relationship `Consumer[Item] <: Consumer[Buyable]`. +Remember, for type `Producer`, it was the other way around, and we had `Producer[Buyable] <: Producer[Item]`. -And in fact, this is sound: The type of `Producer[Buyable].make` only promises us to _return_ a `Buyable`. -As a caller of `make`, we will be happy to also accept a `Book`, which is a subtype of `Buyable`---that is, it is _at least_ a `Buyable`. +And in fact, this is sound. The method `Consumer[Item].take` accepts an `Item`. +As a caller of `take`, we can also supply a `Buyable`, which will be happily accepted by the `Consumer[Item]` since `Buyable` is a subtype of `Item`---that is, it is _at least_ an `Item`. #### Contravariant Types for Consumers From 592063af448278ba521e82dac23ebc6b4fb1122a Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Tue, 15 Jun 2021 12:57:20 -0700 Subject: [PATCH 1512/3075] update FAQ for Scala 3 release (#2074) --- _overviews/FAQ/index.md | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/_overviews/FAQ/index.md b/_overviews/FAQ/index.md index e7d25dbcf5..ba0cce896d 100644 --- a/_overviews/FAQ/index.md +++ b/_overviews/FAQ/index.md @@ -2,14 +2,14 @@ layout: singlepage-overview title: Scala FAQ permalink: /tutorials/FAQ/index.html -redirect_from: +redirect_from: - "/tutorials/FAQ/breakout.html" - "/tutorials/FAQ/chaining-implicits.html" - "/tutorials/FAQ/collections.html" - "/tutorials/FAQ/context-bounds.html" - "/tutorials/FAQ/finding-implicits.html" - "/tutorials/FAQ/finding-symbols.html" - - "/tutorials/FAQ/stream-view.html" + - "/tutorials/FAQ/stream-view.html" - "/tutorials/FAQ/yield.html" --- @@ -35,25 +35,21 @@ are out there; there are many. You can go on the [Scala room on Gitter](https://gitter.im/scala/scala) or another community forum and -ask for book recommendations, but note that you'll get more helpful +ask for book recommendations. You'll get more helpful answers if you provide some information about your background and your reasons for wanting to learn Scala. ### Should I learn Scala 2, or Scala 3? -The default choice remains Scala 2 for now. Most Scala jobs are Scala -2 jobs; most Scala books and online learning materials cover Scala 2; -tooling and library support is strongest in Scala 2; and so on. +Scala 3 was released in May 2021. Because Scala 3 is still so new, +most Scala jobs are Scala 2 jobs; most Scala books and online learning +materials cover Scala 2; tooling and library support is strongest in +Scala 2; and so on. -Scala 3.0.0 is planned for release in 2021, and a number of -Scala 3 books will come out in 2021 as well. In time, there will -be more and more Scala 3 jobs as well. +Thus, Scala 2 remains a common and reasonable choice. -### When is Scala 3 coming out? - -In 2021. Watch the [Scala blog](https://www.scala-lang.org/blog/) -for announcements. For a more detailed view of how work is progressing, -see the [Dotty milestones](https://github.com/lampepfl/dotty/milestones). +Some books that cover Scala 3 are already available; more are on the +way. In time, there will be more and more Scala 3 jobs as well. ### Where are Scala jobs advertised? @@ -181,11 +177,10 @@ differ from a function value such as: val square: Int => Int = x => x * x -[Complete answer on Stack Overflow](https://stackoverflow.com/a/2530007/4111404). - -[Summary with practical differences](https://tpolecat.github.io/2014/06/09/methods-functions.html). +For Scala 2, there is a [complete answer on Stack Overflow](https://stackoverflow.com/a/2530007/4111404) +and a [summary with practical differences](https://tpolecat.github.io/2014/06/09/methods-functions.html). -Note that in **Scala 3** most of the differences will go; +Note that in **Scala 3** the differences are fewer; for example, they will be able to [accept implicit parameters](https://dotty.epfl.ch/docs/reference/contextual/context-functions.html) as well as [type parameters](https://dotty.epfl.ch/docs/reference/new-types/polymorphic-function-types.html). @@ -193,7 +188,7 @@ as well as [type parameters](https://dotty.epfl.ch/docs/reference/new-types/poly Nevertheless, it is still recommended to use methods most of the time, unless you absolutely need a function. And, thanks to [eta-expansion](https://stackoverflow.com/questions/39445018/what-is-the-eta-expansion-in-scala) -you rarely would need to define a function over a method. +you rarely would need to define a function rather than a method. ### What's the difference between types and classes? From d9a05be0d454d9433db78187a13f9b6dee2ebfd4 Mon Sep 17 00:00:00 2001 From: "Lan, Jian" Date: Tue, 15 Jun 2021 14:06:23 -0700 Subject: [PATCH 1513/3075] Fix why-scala-3.md --- _overviews/scala3-book/why-scala-3.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_overviews/scala3-book/why-scala-3.md b/_overviews/scala3-book/why-scala-3.md index e6c5b2bd96..ac74de1606 100644 --- a/_overviews/scala3-book/why-scala-3.md +++ b/_overviews/scala3-book/why-scala-3.md @@ -29,7 +29,6 @@ It’s hard to list every benefit of Scala, but a “Top Ten” list might look - ## 1) FP/OOP fusion More than any other language, Scala supports a fusion of the FP and OOP paradigms. @@ -45,7 +44,7 @@ For instance, a `List` is defined as a class---technically it’s an abstract cl val x = List(1, 2, 3) ``` -However, what appears to the programmer to be a simple `List` is actually built from a combination of several specialized types, including abstract classes named `Iterable`, `Seq`, and `LinearSeq`. +However, what appears to the programmer to be a simple `List` is actually built from a combination of several specialized types, including traits named `Iterable`, `Seq`, and `LinearSeq`. Those types are similarly composed of other small, modular units of code. In addition to building a type like `List` from a series of modular traits, the `List` API also consists of dozens of other methods, many of which are higher-order functions: @@ -106,6 +105,7 @@ val b: Password | Username = if (true) name else password ``` + ## 3) Concise syntax Scala is a low ceremony, “concise but still readable” language. For instance, variable declaration is concise: @@ -176,7 +176,6 @@ These capabilities are described in detail in other sections, so see the [Contex - ## 5) Seamless Java integration Scala/Java interaction is seamless in many ways. @@ -357,6 +356,7 @@ Some of the most important features in this category are: {% comment %} A list of types from the Dotty documentation: + - Inferred types - Generics - Intersection types From fcb797833e2b08cd0e549037109dc1b3450ba86b Mon Sep 17 00:00:00 2001 From: Elias Baldwin Date: Tue, 15 Jun 2021 14:15:45 -0700 Subject: [PATCH 1514/3075] Fix typo on line 131 of domain-modeling-oop.md --- _overviews/scala3-book/domain-modeling-oop.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-book/domain-modeling-oop.md b/_overviews/scala3-book/domain-modeling-oop.md index c06260d84d..56d0972198 100644 --- a/_overviews/scala3-book/domain-modeling-oop.md +++ b/_overviews/scala3-book/domain-modeling-oop.md @@ -128,7 +128,7 @@ In order to allow this, the base class needs to be marked as `open`: ```scala open class Person(name: String) ``` -Marking classes with [`open`][open] is a new feature of Sala 3. Having to explicitly mark classes as open avoids many common pitfalls in OO design. +Marking classes with [`open`][open] is a new feature of Scala 3. Having to explicitly mark classes as open avoids many common pitfalls in OO design. In particular, it requires library designers to explicitly plan for extension and for instance document the classes that are marked as open with additional extension contracts. {% comment %} From 6ca2c3dbcb959eee3424e90a6dea5afdcfa26f6f Mon Sep 17 00:00:00 2001 From: Andrea Peruffo Date: Mon, 24 May 2021 14:40:20 +0100 Subject: [PATCH 1515/3075] Add graalvm AOT notes --- _overviews/jdk-compatibility/overview.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/_overviews/jdk-compatibility/overview.md b/_overviews/jdk-compatibility/overview.md index 880c4a4614..6c6a0e9201 100644 --- a/_overviews/jdk-compatibility/overview.md +++ b/_overviews/jdk-compatibility/overview.md @@ -89,6 +89,16 @@ JDK 17 prereleases are already available. The final release is [targeted](https: The Scala community build doesn't run on JDK 17 yet. We will add it once 17 is closer to release. +## GraalVM Native Image compatibility notes + +There are several records of successfully using Scala with [GraalVM](https://www.graalvm.org) Native Image(i.e.: ahead of time compiler) to produce directly executable binaries. +Beware that, even using solely the Scala standard library, Native Image compilation have some heavy requirements in terms of [reflective access](https://www.graalvm.org/reference-manual/native-image/Reflection/), and it very likely require additional configuration steps to be performed. + +A few sbt plugins are offering support for GraalVM Native Image compilation: + +- [sbt-native-packager](https://www.scala-sbt.org/sbt-native-packager/formats/graalvm-native-image.html) +- [sbt-native-image](https://github.com/scalameta/sbt-native-image) + ## Scala 3 The Scala 3.0.x series supports JDK 8, as well as 11 and beyond. From 57f573092edbb37d038da4d8f479a115757aa89e Mon Sep 17 00:00:00 2001 From: Theofanis Despoudis <328805+theodesp@users.noreply.github.com> Date: Wed, 9 Jun 2021 16:36:21 +0100 Subject: [PATCH 1516/3075] Update learn.md Removed ScalaCourses expired link for consistency and less confusion --- learn.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/learn.md b/learn.md index 2204c55f1d..19af2b78c9 100644 --- a/learn.md +++ b/learn.md @@ -101,9 +101,6 @@ You can visit his [YouTube channel](https://www.youtube.com/user/DrMarkCLewis/fe ## allaboutscala [allaboutscala](https://allaboutscala.com/) provides detailed tutorials for beginners. -## ScalaCourses -[Independent Courseware](https://getscala.com), online self-study or instructor-led Scala and Play courses for a fee. - ## DevInsideYou [DevInsideYou](https://youtube.com/devinsideyou) is a YouTube channel with hundreds of hours of free Scala content. From e2aa390b9d5ba0410181c84a64f9ed2990455ca0 Mon Sep 17 00:00:00 2001 From: kenji yoshida <6b656e6a69@gmail.com> Date: Sat, 19 Jun 2021 04:53:48 +0900 Subject: [PATCH 1517/3075] Create CODEOWNERS https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-code-owners --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/CODEOWNERS diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..ce1bb0f48b --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +/_ja @scala/docs-ja From af81dade1616289e5bc5e01404322713ba433582 Mon Sep 17 00:00:00 2001 From: Myyk Seok Date: Sat, 19 Jun 2021 16:34:05 +0800 Subject: [PATCH 1518/3075] Fix typo: eather -> either --- _overviews/scala3-migration/incompat-dropped-features.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-migration/incompat-dropped-features.md b/_overviews/scala3-migration/incompat-dropped-features.md index 2ba51e4a86..a8fe9b7789 100644 --- a/_overviews/scala3-migration/incompat-dropped-features.md +++ b/_overviews/scala3-migration/incompat-dropped-features.md @@ -204,7 +204,7 @@ Existential type is a [dropped feature](https://dotty.epfl.ch/docs/reference/dro def foo: List[Class[T]] forSome { type T } // Error: Existential types are no longer supported ``` -> Existential type is an experimental feature in Scala 2.13 that must be enabled explicitly eather by importing `import scala.language.existentials` or by setting the `-language:existentials` compiler flag. +> Existential type is an experimental feature in Scala 2.13 that must be enabled explicitly either by importing `import scala.language.existentials` or by setting the `-language:existentials` compiler flag. The proposed solution is to introduce an enclosing type that carries the dependent type: From 9ce11019bb8bfb0796a39af4503fa3d277113943 Mon Sep 17 00:00:00 2001 From: Abhishek Vyas <44902551+abhi887@users.noreply.github.com> Date: Mon, 21 Jun 2021 00:22:10 +0530 Subject: [PATCH 1519/3075] scala-for-python-devs.md creating multiline string variables Added an example for creating multiline string variables --- _overviews/scala3-book/scala-for-python-devs.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/_overviews/scala3-book/scala-for-python-devs.md b/_overviews/scala3-book/scala-for-python-devs.md index b045e67ac6..4a39f4ee27 100644 --- a/_overviews/scala3-book/scala-for-python-devs.md +++ b/_overviews/scala3-book/scala-for-python-devs.md @@ -136,13 +136,19 @@ These examples demonstrate how to create variables in Python and Scala. x = 1 -
x = "Hi"
+
x = "Hi" +
x = """foo +
       bar +
       baz"""
val x = 1 -
val x = "Hi"
+
val x = "Hi" +
val x = """foo +
           bar +
           baz"""
From 652241943ce762bbd488461a257e61cd640321c6 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Mon, 21 Jun 2021 14:23:35 +0100 Subject: [PATCH 1520/3075] compatibility example has wrong scala version --- _overviews/scala3-migration/compatibility-classpath.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_overviews/scala3-migration/compatibility-classpath.md b/_overviews/scala3-migration/compatibility-classpath.md index e9d71d65ab..521b2e448b 100644 --- a/_overviews/scala3-migration/compatibility-classpath.md +++ b/_overviews/scala3-migration/compatibility-classpath.md @@ -113,13 +113,13 @@ Or, in case `bar` is a published Scala 3 library: ```scala lazy val foo = project.in.file("foo") .settings( - scalaVersion := "3.0.0", + scalaVersion := "2.13.6", scalacOptions += "-Ytasty-reader", libraryDependencies += ("org.bar" %% "bar" % "1.0.0").cross(CrossVersion.for2_13Use3) ) ``` -Similarly to `CrossVersion.for2_13Use3`, we use `CrossVersion.for3Use2_13` in sbt to resolve `bar_2.13` instead of `bar_3`. +Similarly to `CrossVersion.for2_13Use3`, we use `CrossVersion.for3Use2_13` in sbt to resolve `bar_3` instead of `bar_2.13`. ## Interoperability Overview From ce031b5be7d04107c96c22e9afdbc850e6634a2e Mon Sep 17 00:00:00 2001 From: Abhishek Vyas <44902551+abhi887@users.noreply.github.com> Date: Mon, 21 Jun 2021 19:34:38 +0530 Subject: [PATCH 1521/3075] updated identifiers for multiline string and dictionary variables updated identifiers for multiline string variables and dictionary/map variable in scala-for-python-devs.md --- _overviews/scala3-book/scala-for-python-devs.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_overviews/scala3-book/scala-for-python-devs.md b/_overviews/scala3-book/scala-for-python-devs.md index 4a39f4ee27..0934989d4e 100644 --- a/_overviews/scala3-book/scala-for-python-devs.md +++ b/_overviews/scala3-book/scala-for-python-devs.md @@ -137,7 +137,7 @@ These examples demonstrate how to create variables in Python and Scala. x = 1
x = "Hi" -
x = """foo +
y = """foo
       bar
       baz"""
@@ -146,7 +146,7 @@ These examples demonstrate how to create variables in Python and Scala. val x = 1
val x = "Hi" -
val x = """foo +
val y = """foo
           bar
           baz"""
@@ -186,7 +186,7 @@ These examples demonstrate how to create variables in Python and Scala. - val movies = Map( + val x = Map(
  "Toy Story" -> 8.3,
  "Forrest Gump" -> 8.8,
  "Cloud Atlas" -> 7.4 From 5f734205a00ae937f335c59e5fed26d4d6b69cf9 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Mon, 21 Jun 2021 13:39:55 -0700 Subject: [PATCH 1522/3075] fix Error Formatting page --- _data/overviews.yml | 2 +- _overviews/compiler-options/errors.md | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/_data/overviews.yml b/_data/overviews.yml index 1764f6bc5e..54bb90a02b 100644 --- a/_data/overviews.yml +++ b/_data/overviews.yml @@ -257,7 +257,7 @@ - title: Error Formatting by: Torsten Schmits icon: cog - url: "compiler-options/index.html" + url: "compiler-options/errors.html" description: "A new engine for more user-friendly error messages, printing chains of dependent implicits and colored found/required type diffs." diff --git a/_overviews/compiler-options/errors.md b/_overviews/compiler-options/errors.md index f6e7823689..8128ef96ae 100644 --- a/_overviews/compiler-options/errors.md +++ b/_overviews/compiler-options/errors.md @@ -1,3 +1,8 @@ +--- +layout: singlepage-overview +title: Error Formatting +--- + # Introduction An advanced mechanism for formatting type errors and inspecting missing From 7c7eb8499a26b7ea7a1b07074dc3a25f4f431e4a Mon Sep 17 00:00:00 2001 From: Dean Wampler Date: Tue, 22 Jun 2021 16:08:18 -0500 Subject: [PATCH 1523/3075] Updated Programming Scala book images --- .../books/ProgrammingScala-final-border.gif | Bin 5574 -> 5619 bytes resources/img/books/ProgrammingScala.jpg | Bin 42408 -> 60005 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/resources/img/books/ProgrammingScala-final-border.gif b/resources/img/books/ProgrammingScala-final-border.gif index 69f7cb8cad766bf0185700a2712858f73f7d9c8a..a8646acbdd87d5a7b1ee0fd9fd9c85b2f2048c81 100644 GIT binary patch literal 5619 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 YT)^)+s+S#2M=?0SZl|3b1c6Qe2dyeKE&u=k literal 5574 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 diff --git a/resources/img/books/ProgrammingScala.jpg b/resources/img/books/ProgrammingScala.jpg index 07db7ec46afc58b6c3f551498481de25399610a8..232d0abff801c3f66ec604c7a3432d4d71635341 100644 GIT binary patch literal 60005 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μ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 Date: Tue, 22 Jun 2021 16:35:27 -0500 Subject: [PATCH 1524/3075] Updated content for Programming Scala by Dean Wampler --- _books/2-programming-scala.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_books/2-programming-scala.md b/_books/2-programming-scala.md index 27a1e9ce61..8fc729169f 100644 --- a/_books/2-programming-scala.md +++ b/_books/2-programming-scala.md @@ -1,11 +1,11 @@ --- title: "Programming Scala" -link: https://shop.oreilly.com/product/0636920033073.do +link: http://programming-scala.com image: /resources/img/books/ProgrammingScala-final-border.gif -status: Updated for Scala 2.12 -authors: ["Alex Payne", "Dean Wampler"] +status: Updated for Scala 3 +authors: ["Dean Wampler"] publisher: O’Reilly publisherLink: https://www.oreilly.com/ --- -Both are industry experts, Alex Payne being the lead API programmer at Twitter, a social networking service based on Scala. O’Reilly, the publisher, writes: "Learn how to be more productive with Scala, a new multi-paradigm language for the Java Virtual Machine (JVM) that integrates features of both object-oriented and functional programming. With this book, you'll discover why Scala is ideal for highly scalable, component-based applications that support concurrency and distribution. You'll also learn how to leverage the wealth of Java class libraries to meet the practical needs of enterprise and Internet projects more easily." +Dean is a well-known member of the Scala community, using Scala recently for streaming data systems at Lightbend and now at Domino Data Lab. This edition covers the new features of Scala 3, with comparisons to Scala 2, both to explain why the changes were made and how they improve Scala, and also to enable developers using mixed Scala 2 and 3 code bases to work effectively. The book is aimed at professional programmers who want a comprehensive, in-depth, yet pragmatic tour of Scala and best practices for using it. From bcad9c105fc521b4bff0661017dede35c17042c0 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Wed, 23 Jun 2021 13:49:51 -0700 Subject: [PATCH 1525/3075] update JDK 17 info on JDK compatiblity page --- _overviews/jdk-compatibility/overview.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/_overviews/jdk-compatibility/overview.md b/_overviews/jdk-compatibility/overview.md index 6c6a0e9201..85e65f3448 100644 --- a/_overviews/jdk-compatibility/overview.md +++ b/_overviews/jdk-compatibility/overview.md @@ -12,8 +12,8 @@ Sometimes new JVM and JDK (Java Development Kit) versions require us to update S | JDK version | Minimum Scala versions | Recommended Scala versions | |:-----------:|:---------------------------------|:-----------------------------------------------------------| -| 17 | 2.13.6, 2.12.14 (see below) | 2.13.6, 2.12.14 (see below) -| 16 | 2.13.5, 2.12.14 | 2.13.6, 2.12.14 +| 17 | 2.13.6, 2.12.15 (forthcoming) | 2.13.6, 2.12.15 (forthcoming) | +| 16 | 2.13.5, 2.12.14 | 2.13.6, 2.12.14 | | 13, 14, 15 | 2.13.2, 2.12.11 | 2.13.6, 2.12.14 | | 12 | 2.13.1, 2.12.9 | 2.13.6, 2.12.14 | | 11 | 2.13.0, 2.12.4, 2.11.12 | 2.13.6, 2.12.14, 2.11.12 | @@ -81,13 +81,15 @@ As far as we know, 12, 13, 14, and 15 are similar to 11 with respect to Scala co JDK 16 was released in March 2021. It is not an LTS release, so the remarks above about non-LTS releases apply. The next LTS release will be JDK 17. -The Scala community build and the Scala build and test suite run on JDK 16. We shipped improved JDK 16 support in [Scala 2.13.5](https://github.com/scala/scala/releases/tag/v2.13.5) and intend to ship the same improvements soon in Scala 2.12.14 ([release timing thread](https://contributors.scala-lang.org/t/scala-2-12-14-planning/4852/2)). +The Scala build and test suite pass on JDK 16, and so does most of the Scala community build. We shipped improved JDK 16 support in [Scala 2.13.5](https://github.com/scala/scala/releases/tag/v2.13.5) and [2.12.14](https://github.com/scala/scala/releases/tag/v2.12.14). ## JDK 17 compatibility notes -JDK 17 prereleases are already available. The final release is [targeted](https://openjdk.java.net/projects/jdk/17/) for September 2021. JDK 17 will be an LTS release. +JDK 17 prereleases are already available. As of June 2021, the feature set is frozen. The final release is [targeted](https://openjdk.java.net/projects/jdk/17/) for September 2021. JDK 17 will be an LTS release. -The Scala community build doesn't run on JDK 17 yet. We will add it once 17 is closer to release. +The Scala community build is mostly green on JDK 17, as of June 2021. We are in the process of making Scala's own build and test suite pass. + +Scala 2.13.6 already supports JDK 17. Scala 2.12.14 mostly works as well, but there is a known issue with lambda deserialiation; a fix will ship in Scala 2.12.15 (see [release timing thread](https://contributors.scala-lang.org/t/scala-2-12-15-planning/5152)). ## GraalVM Native Image compatibility notes @@ -101,6 +103,6 @@ A few sbt plugins are offering support for GraalVM Native Image compilation: ## Scala 3 -The Scala 3.0.x series supports JDK 8, as well as 11 and beyond. +The Scala 3.x series supports JDK 8, as well as 11 and beyond. -As Scala and the JVM continue to evolve, some eventual Scala 3.x version may drop support for JDK 8, in order to better take advantage of new JVM features. It isn't clear yet what the new minimum supported version might become. +As Scala and the JVM continue to evolve, some eventual Scala version may drop support for JDK 8, in order to better take advantage of new JVM features. It isn't clear yet what the new minimum supported version might become. From 0e4bce98931a9a0e4d3ab5c75b5a28905207f444 Mon Sep 17 00:00:00 2001 From: Liam Bohl Date: Thu, 24 Jun 2021 11:37:33 -0400 Subject: [PATCH 1526/3075] Replaced functions deprecated as of 2.13 += (varargs) -> ++= -= (varargs) -> --= retain -> filterInPlace --- _overviews/scala-book/collections-maps.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_overviews/scala-book/collections-maps.md b/_overviews/scala-book/collections-maps.md index 1556a66ef8..95e890bbc3 100644 --- a/_overviews/scala-book/collections-maps.md +++ b/_overviews/scala-book/collections-maps.md @@ -83,18 +83,18 @@ Here are some things you can do with a mutable `Map`: ```scala // add elements with += states += ("AZ" -> "Arizona") -states += ("CO" -> "Colorado", "KY" -> "Kentucky") +states ++= Map("CO" -> "Colorado", "KY" -> "Kentucky") // remove elements with -= states -= "KY" -states -= ("AZ", "CO") +states --= List("AZ", "CO") // update elements by reassigning them states("AK") = "Alaska, The Big State" -// retain elements by supplying a function that operates on +// filter elements by supplying a function that operates on // the keys and/or values -states.retain((k,v) => k == "AK") +states.filterInPlace((k,v) => k == "AK") ``` From 8c0d3389302ac608fc436dc61a149dce5b723812 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Thu, 24 Jun 2021 08:40:05 -0700 Subject: [PATCH 1527/3075] tweak wording around community build as per Lukas's feedback --- _overviews/jdk-compatibility/overview.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_overviews/jdk-compatibility/overview.md b/_overviews/jdk-compatibility/overview.md index 85e65f3448..dd151bf707 100644 --- a/_overviews/jdk-compatibility/overview.md +++ b/_overviews/jdk-compatibility/overview.md @@ -81,13 +81,13 @@ As far as we know, 12, 13, 14, and 15 are similar to 11 with respect to Scala co JDK 16 was released in March 2021. It is not an LTS release, so the remarks above about non-LTS releases apply. The next LTS release will be JDK 17. -The Scala build and test suite pass on JDK 16, and so does most of the Scala community build. We shipped improved JDK 16 support in [Scala 2.13.5](https://github.com/scala/scala/releases/tag/v2.13.5) and [2.12.14](https://github.com/scala/scala/releases/tag/v2.12.14). +The Scala build and test suite pass on JDK 16, and so does the Scala community build. We shipped improved JDK 16 support in [Scala 2.13.5](https://github.com/scala/scala/releases/tag/v2.13.5) and [2.12.14](https://github.com/scala/scala/releases/tag/v2.12.14). ## JDK 17 compatibility notes JDK 17 prereleases are already available. As of June 2021, the feature set is frozen. The final release is [targeted](https://openjdk.java.net/projects/jdk/17/) for September 2021. JDK 17 will be an LTS release. -The Scala community build is mostly green on JDK 17, as of June 2021. We are in the process of making Scala's own build and test suite pass. +The Scala community build passes on JDK 17. We are in the process of making Scala's own build and test suite pass. Scala 2.13.6 already supports JDK 17. Scala 2.12.14 mostly works as well, but there is a known issue with lambda deserialiation; a fix will ship in Scala 2.12.15 (see [release timing thread](https://contributors.scala-lang.org/t/scala-2-12-15-planning/5152)). From bcd05f58cb46217358858002a9e17be6a57f2699 Mon Sep 17 00:00:00 2001 From: Dmitrii Naumenko Date: Thu, 24 Jun 2021 19:01:58 +0300 Subject: [PATCH 1528/3075] Update ca-given-imports.md --- _overviews/scala3-book/ca-given-imports.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-book/ca-given-imports.md b/_overviews/scala3-book/ca-given-imports.md index 2b5c0a6429..6cfb436a29 100644 --- a/_overviews/scala3-book/ca-given-imports.md +++ b/_overviews/scala3-book/ca-given-imports.md @@ -14,7 +14,7 @@ The basic form is shown in this example: ```scala object A: class TC - given tc as TC + given tc: TC = ??? def f(using TC) = ??? object B: From c3a58d34c576e4798bc141ac7967117a81331920 Mon Sep 17 00:00:00 2001 From: Altair-Bueno <67512202+Altair-Bueno@users.noreply.github.com> Date: Thu, 24 Jun 2021 19:30:21 +0200 Subject: [PATCH 1529/3075] Using Scala 2 If-else expression instead if () else syntax is from Scala 2. Use if then else instead or simplify it by removing the if-else expression. If-else is unnecessary --- _overviews/scala3-book/taste-objects.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/_overviews/scala3-book/taste-objects.md b/_overviews/scala3-book/taste-objects.md index ae522627f1..5c27e3b8a9 100644 --- a/_overviews/scala3-book/taste-objects.md +++ b/_overviews/scala3-book/taste-objects.md @@ -27,8 +27,7 @@ For example, this `StringUtils` object contains a small collection of string-rel ```scala object StringUtils: - def isNullOrEmpty(s: String): Boolean = - if (s==null || s.trim.equals("")) true else false + def isNullOrEmpty(s: String): Boolean = s==null || s.trim.equals("") def leftTrim(s: String): String = s.replaceAll("^\\s+", "") def rightTrim(s: String): String = s.replaceAll("\\s+$", "") ``` From 662cf053d5c84f5e11650e4e6787b41ed34c4d08 Mon Sep 17 00:00:00 2001 From: Altair-Bueno <67512202+Altair-Bueno@users.noreply.github.com> Date: Fri, 25 Jun 2021 11:28:03 +0200 Subject: [PATCH 1530/3075] Added @SethTisue suggestion --- _overviews/scala3-book/taste-objects.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-book/taste-objects.md b/_overviews/scala3-book/taste-objects.md index 5c27e3b8a9..6e33d8fd55 100644 --- a/_overviews/scala3-book/taste-objects.md +++ b/_overviews/scala3-book/taste-objects.md @@ -27,7 +27,7 @@ For example, this `StringUtils` object contains a small collection of string-rel ```scala object StringUtils: - def isNullOrEmpty(s: String): Boolean = s==null || s.trim.equals("") + def isNullOrEmpty(s: String): Boolean = s==null || s.trim == "" def leftTrim(s: String): String = s.replaceAll("^\\s+", "") def rightTrim(s: String): String = s.replaceAll("\\s+$", "") ``` From 430252a1766eb0062784ad992d78eec516965b27 Mon Sep 17 00:00:00 2001 From: Altair-Bueno <67512202+Altair-Bueno@users.noreply.github.com> Date: Fri, 25 Jun 2021 11:29:44 +0200 Subject: [PATCH 1531/3075] Update taste-objects.md --- _overviews/scala3-book/taste-objects.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-book/taste-objects.md b/_overviews/scala3-book/taste-objects.md index 6e33d8fd55..2e6d1428ca 100644 --- a/_overviews/scala3-book/taste-objects.md +++ b/_overviews/scala3-book/taste-objects.md @@ -27,7 +27,7 @@ For example, this `StringUtils` object contains a small collection of string-rel ```scala object StringUtils: - def isNullOrEmpty(s: String): Boolean = s==null || s.trim == "" + def isNullOrEmpty(s: String): Boolean = s==null || s.trim.isEmpty def leftTrim(s: String): String = s.replaceAll("^\\s+", "") def rightTrim(s: String): String = s.replaceAll("\\s+$", "") ``` From f8b8af443956c64769a7577ed0882b182ec8d87e Mon Sep 17 00:00:00 2001 From: Altair-Bueno <67512202+Altair-Bueno@users.noreply.github.com> Date: Fri, 25 Jun 2021 13:06:17 +0200 Subject: [PATCH 1532/3075] Found another Scala 2 `isNullOrEmpty` --- _overviews/scala3-book/domain-modeling-tools.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/_overviews/scala3-book/domain-modeling-tools.md b/_overviews/scala3-book/domain-modeling-tools.md index b8fd76f2fc..f59c39c8af 100644 --- a/_overviews/scala3-book/domain-modeling-tools.md +++ b/_overviews/scala3-book/domain-modeling-tools.md @@ -219,8 +219,7 @@ Here’s an example of a “string utilities” object that contains a set of me object StringUtils: def truncate(s: String, length: Int): String = s.take(length) def containsWhitespace(s: String): Boolean = s.matches(".*\\s.*") - def isNullOrEmpty(s: String): Boolean = - if s == null || s.trim.equals("") then true else false + def isNullOrEmpty(s: String): Boolean = s==null || s.trim.isEmpty ``` We can use the object as follows: From cb136c0b509d438348c6e9737eb0fb55a7d119fe Mon Sep 17 00:00:00 2001 From: Jentsch Date: Sat, 26 Jun 2021 11:52:38 +0200 Subject: [PATCH 1533/3075] Fix docker port in Readme.md docker-compose.yml:7 exposes the port on 4000 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eef762ce16..8b3d557025 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ To build and view site with docker: docker-compose up -It will incrementally build and serve site at `http://localhost:8080` +It will incrementally build and serve site at `http://localhost:4000` ## Contributing ## From 904fdf7d95ce146f37c1ab1ee37c0ecf41917916 Mon Sep 17 00:00:00 2001 From: Genghis Yang Date: Sat, 26 Jun 2021 19:56:02 +0800 Subject: [PATCH 1534/3075] Fix a typo in Domain Modeling / Tools I believe `have also have` is not grammatical. Should be `also have` --- _overviews/scala3-book/domain-modeling-tools.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-book/domain-modeling-tools.md b/_overviews/scala3-book/domain-modeling-tools.md index b8fd76f2fc..e994551aff 100644 --- a/_overviews/scala3-book/domain-modeling-tools.md +++ b/_overviews/scala3-book/domain-modeling-tools.md @@ -66,7 +66,7 @@ p.vocation = "Musician" ### Fields and methods -Classes can have also have methods and additional fields that are not part of constructors. +Classes can also have methods and additional fields that are not part of constructors. They are defined in the body of the class. The body is initialized as part of the default constructor: From 4d0e5d3baae763f96046c2d7ad5b8a6d4658c165 Mon Sep 17 00:00:00 2001 From: Genghis Yang Date: Sat, 26 Jun 2021 21:18:08 +0800 Subject: [PATCH 1535/3075] Fix a typo in scala 3 book domain modeling fp Just a typo --- _overviews/scala3-book/domain-modeling-fp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-book/domain-modeling-fp.md b/_overviews/scala3-book/domain-modeling-fp.md index dec7dda6d2..9d1c163864 100644 --- a/_overviews/scala3-book/domain-modeling-fp.md +++ b/_overviews/scala3-book/domain-modeling-fp.md @@ -259,7 +259,7 @@ Pizza.price(pizza1) Grouping functionality this way has a few advantages: - It associates functionality with data and makes it easier to find for programmers (and the compiler). -- It creates a namespace and for instance let's us use `price` as a method name without having to rely on overloading. +- It creates a namespace and for instance let's use `price` as a method name without having to rely on overloading. - The implementation of `Topping.price` can access enumeration values like `Cheese` without having to import them. However, there are also a few tradeoffs that should be considered: From 8bd14057ecc07ae2b9c82ba0acc228812e9b7dc3 Mon Sep 17 00:00:00 2001 From: Mario Galic Date: Sat, 10 Apr 2021 19:07:47 +0100 Subject: [PATCH 1536/3075] Conversion Between Option and the Collections - Clarify if Option is considered a collection by summarising discussion at Make Option extend IterableOnce #8038 - Document implicit conversion option2iterable --- ...sion-between-option-and-the-collections.md | 53 +++++++++++++++++++ ...ions-between-java-and-scala-collections.md | 1 + 2 files changed, 54 insertions(+) create mode 100644 _overviews/collections-2.13/conversion-between-option-and-the-collections.md diff --git a/_overviews/collections-2.13/conversion-between-option-and-the-collections.md b/_overviews/collections-2.13/conversion-between-option-and-the-collections.md new file mode 100644 index 0000000000..7fff2ea548 --- /dev/null +++ b/_overviews/collections-2.13/conversion-between-option-and-the-collections.md @@ -0,0 +1,53 @@ +--- +layout: multipage-overview +title: Conversion Between Option and the Collections +partof: collections-213 +overview-name: Collections + +num: 18 +previous-page: conversions-between-java-and-scala-collections + +permalink: /overviews/collections-2.13/:title.html +--- +`Option` can be seen as a collection that has zero or exactly one element, and it provides a degree of interoperability with the collection types found in the package `scala.collection`. In particular, it implements the interface `IterableOnce`, which models the simplest form of collections: something that can be iterated over, at least once. However, `Option` does not implement the more comprehensive interface of `Iterable`. Indeed, we cannot provide a sensible implementation for the operation [`fromSpecific`](https://github.com/scala/scala/blob/6c68c2825e893bb71d6dc78465ac8c6f415cbd93/src/library/scala/collection/Iterable.scala#L173), which is supposed to create an `Option` from a collection of possibly more than one element. Starting from [Scala 2.13](https://github.com/scala/scala/pull/8038), `Option` was made an `IterableOnce` but not an `Iterable`. + +Hence `Option` can be used everywhere an `IterableOnce` is expected, for example, when calling `flatMap` on a collection (or inside a for-comprehension) + +```scala mdoc +for { + a <- Set(1) + b <- Option(41) +} yield (a + b) +// : Set[Int] = Set(42) +``` + +since the operation `flatMap` on the type `Set[Int]` takes a function returning an `IterableOnce`: + +``` +def flatMap[B](f: Int => IterableOnce[B]): Set[B] +``` + +Although `Option` does not extend `Iterable`, there exists an [implicit conversion](https://github.com/scala/scala/blob/6c68c2825e893bb71d6dc78465ac8c6f415cbd93/src/library/scala/Option.scala#L19) between `Option` and `Iterable` + + +``` +implicit def option2Iterable[A](xo: Option[A]): Iterable[A] +``` + +so although `Option[A]` is not a full collection it can be _viewed_ as one. For example, + +```scala mdoc +Some(42).drop(1) +// : Iterable[Int] = List() +``` + +expands to + +```scala mdoc +Option.option2Iterable(Some(42)).drop(1) +// : Iterable[Int] = List() +``` + +because `drop` is not defined on `Option`. A downside of the above implicit conversion is that instead of getting back an `Option[A]` we are left with an `Iterable[A]`. For this reason, `Option`’s documentation carries the following note: + +> Many of the methods in `Option` are duplicative with those in the `Iterable` hierarchy, but they are duplicated for a reason: the implicit conversion tends to leave one with an `Iterable` in situations where one could have retained an `Option`. diff --git a/_overviews/collections-2.13/conversions-between-java-and-scala-collections.md b/_overviews/collections-2.13/conversions-between-java-and-scala-collections.md index 86070db314..b4090053ba 100644 --- a/_overviews/collections-2.13/conversions-between-java-and-scala-collections.md +++ b/_overviews/collections-2.13/conversions-between-java-and-scala-collections.md @@ -6,6 +6,7 @@ overview-name: Collections num: 17 previous-page: creating-collections-from-scratch +next-page: conversion-between-option-and-the-collections languages: [ru] permalink: /overviews/collections-2.13/:title.html From 824a0ab96c40c373fa2b4372098cfe079c696e0b Mon Sep 17 00:00:00 2001 From: Genghis Yang Date: Mon, 28 Jun 2021 16:13:54 +0800 Subject: [PATCH 1537/3075] Fix typo --- _overviews/scala3-book/domain-modeling-fp.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-book/domain-modeling-fp.md b/_overviews/scala3-book/domain-modeling-fp.md index 9d1c163864..31e5d19008 100644 --- a/_overviews/scala3-book/domain-modeling-fp.md +++ b/_overviews/scala3-book/domain-modeling-fp.md @@ -259,7 +259,7 @@ Pizza.price(pizza1) Grouping functionality this way has a few advantages: - It associates functionality with data and makes it easier to find for programmers (and the compiler). -- It creates a namespace and for instance let's use `price` as a method name without having to rely on overloading. +- It creates a namespace and for instance lets us use `price` as a method name without having to rely on overloading. - The implementation of `Topping.price` can access enumeration values like `Cheese` without having to import them. However, there are also a few tradeoffs that should be considered: From 923bb72a713bef577cde546368a30c4a1e2d59d9 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Mon, 21 Jun 2021 15:01:12 +0200 Subject: [PATCH 1538/3075] Suggestions on the Scala 3 book (part 5) --- _overviews/scala3-book/concurrency.md | 63 ++++++++----- .../scala3-book/interacting-with-java.md | 11 ++- _overviews/scala3-book/scala-for-java-devs.md | 23 +++-- .../scala3-book/scala-for-javascript-devs.md | 7 +- .../scala3-book/scala-for-python-devs.md | 34 ++++--- _overviews/scala3-book/scala-tools.md | 89 +++++++++++++------ 6 files changed, 139 insertions(+), 88 deletions(-) diff --git a/_overviews/scala3-book/concurrency.md b/_overviews/scala3-book/concurrency.md index 59b86b0815..bda65f21a9 100644 --- a/_overviews/scala3-book/concurrency.md +++ b/_overviews/scala3-book/concurrency.md @@ -55,7 +55,8 @@ You’ll also see examples of methods that are used to handle the value in a fut > When you think about futures, it’s important to know that they’re intended as a one-shot, “Handle this relatively slow computation on some other thread, and call me back with a result when you’re done” construct. > As a point of contrast, [Akka](https://akka.io) actors are intended to run for a long time and respond to many requests during their lifetime. -> While an actor may live forever, a future is intended to be run only once. +> While an actor may live forever, a future eventually contains the result +> of a computation that ran only once. @@ -77,7 +78,7 @@ Now you’re ready to create a future. For this example, first define a long-running, single-threaded algorithm: ```scala -def longRunningAlgorithm = +def longRunningAlgorithm() = Thread.sleep(10_000) 42 ``` @@ -86,29 +87,29 @@ That fancy algorithm returns the integer value `42` after a ten second delay. Now call that algorithm by wrapping it into the `Future` constructor, and assigning the result to a variable: ```scala -scala> val f = Future(longRunningAlgorithm) -f: scala.concurrent.Future[Int] = Future() +scala> val eventualInt = Future(longRunningAlgorithm()) +eventualInt: scala.concurrent.Future[Int] = Future() ``` -Right away your future begins running. -If you immediately check the value of the variable `f`, you see that the future hasn’t completed yet: +Right away, your computation---the call to `longRunningAlgorithm()`---begins running. +If you immediately check the value of the variable `eventualInt`, you see that the future hasn’t been completed yet: ```scala -scala> f +scala> eventualInt val res1: scala.concurrent.Future[Int] = Future() ``` -But if you check again after ten seconds, you’ll see that it completes successfully: +But if you check again after ten seconds, you’ll see that it is completed successfully: ```scala -scala> f +scala> eventualInt val res2: scala.concurrent.Future[Int] = Future(Success(42)) ``` While that’s a relatively simple example, it shows the basic approach: Just construct a new `Future` with your long-running algorithm. One thing to notice is that the `42` you expected is wrapped in a `Success`, which is further wrapped in a `Future`. -This is a key concept to understand: the value in a `Future` is always an instance of one of the *scala.util.Try* types: `Success` or `Failure`. +This is a key concept to understand: the value in a `Future` is always an instance of one of the `scala.util.Try` types: `Success` or `Failure`. Therefore, when you work with the result of a future, you use the usual `Try`-handling techniques. @@ -118,7 +119,7 @@ Therefore, when you work with the result of a future, you use the usual `Try`-ha This is what the result looks like when you call `map` right after creating the variable `f`: ```scala -scala> val a = f.map(_ * 2) +scala> val a = eventualInt.map(_ * 2) a: scala.concurrent.Future[Int] = Future() ``` @@ -139,13 +140,13 @@ In addition to higher-order functions like `map`, you can also use callback meth One commonly used callback method is `onComplete`, which takes a *partial function* in which you handle the `Success` and `Failure` cases: ```scala -f.onComplete { +eventualInt.onComplete { case Success(value) => println(s"Got the callback, value = $value") case Failure(e) => e.printStackTrace } ``` -When you paste that code in the REPL you’ll see the result: +When you paste that code in the REPL you’ll eventually see the result: ```scala Got the callback, value = 42 @@ -180,10 +181,11 @@ See the [Futures and Promises][futures] page for a discussion of additional meth ## Running multiple futures and joining their results -To run multiple futures in parallel and join their results when all of the futures complete, use a `for` expression. +To run multiple computations in parallel and join their results when all of the futures have been completed, use a `for` expression. + The correct approach is: -1. Create the futures +1. Start the computations that return `Future` results 2. Merge their results in a `for` expression 3. Extract the merged result using `onComplete` or a similar technique @@ -191,27 +193,27 @@ The correct approach is: ### An example The three steps of the correct approach are shown in the following example. -A key is that you first create the futures and then join them in the `for` expression: +A key is that you first start the computations that return futures, and then join them in the `for` expression: ```scala import scala.concurrent.Future import scala.concurrent.ExecutionContext.Implicits.global import scala.util.{Failure, Success} -val startTime = System.currentTimeMillis -def delta() = System.currentTimeMillis - startTime +val startTime = System.currentTimeMillis() +def delta() = System.currentTimeMillis() - startTime def sleep(millis: Long) = Thread.sleep(millis) @main def multipleFutures1 = println(s"creating the futures: ${delta()}") - // (1) create the futures + // (1) start the computations that return futures val f1 = Future { sleep(800); 1 } // eventually returns 1 val f2 = Future { sleep(200); 2 } // eventually returns 2 val f3 = Future { sleep(400); 3 } // eventually returns 3 - // (2) run them simultaneously in a `for` expression + // (2) join the futures in a `for` expression val result = for r1 <- f1 @@ -251,10 +253,23 @@ All of that code is run on the JVM’s main thread. Then, at 806 ms, the three futures complete and the code in the `yield` block is run. Then the code immediately goes to the `Success` case in the `onComplete` method. -The 806 ms output is a key to seeing that the three futures are run in parallel. -If they were run sequentially, the total time would be about 1,400 ms---the sum of the sleep times of the three futures. -But because they’re run in parallel, the total time is just slightly longer than the longest-running future: `f1`, which is 800 ms. - +The 806 ms output is a key to seeing that the three computations are run in parallel. +If they were run sequentially, the total time would be about 1,400 ms---the sum of the sleep times of the three computations. +But because they’re run in parallel, the total time is just slightly longer than the longest-running computation: `f1`, which is 800 ms. + +> Notice that if the computations were run within the `for` expression, they +> would be executed sequentially, not in parallel: +> ~~~ +> // Sequential execution (no parallelism!) +> for +> r1 <- Future { sleep(800); 1 } +> r2 <- Future { sleep(200); 2 } +> r3 <- Future { sleep(400); 3 } +> yield +> r1 + r2 + r3 +> ~~~ +> So, if you want the computations to be possibly run in parallel, remember +> to run them outside of the `for` expression. ### A method that returns a future diff --git a/_overviews/scala3-book/interacting-with-java.md b/_overviews/scala3-book/interacting-with-java.md index 36ceb7fe58..8ccb38e156 100644 --- a/_overviews/scala3-book/interacting-with-java.md +++ b/_overviews/scala3-book/interacting-with-java.md @@ -58,9 +58,8 @@ You can convert that Java list to a Scala `Seq`, using the conversion utilities ```scala // scala import scala.jdk.CollectionConverters.* -import java.util.List -def testList = +def testList() = println("Using a Java List in Scala") val javaList: java.util.List[String] = JavaClass.getStrings() val scalaSeq: Seq[String] = javaList.asScala.toSeq @@ -156,7 +155,7 @@ class Dog extends Animal, Wagging, Running: ## How to use Scala collections in Java -When you need to use a Scala collection class in your Java code, use the methods of Scala’s _scala.jdk.javaapi.CollectionConverters_ object in your Java code to make the conversions work. +When you need to use a Scala collection class in your Java code, use the methods of Scala’s `scala.jdk.javaapi.CollectionConverters` object in your Java code to make the conversions work. For example, if you have a `List[String]` like this in a Scala class: ```scala @@ -192,7 +191,7 @@ Here are a few things to notice in that code: ## How to use Scala `Option` in Java -When you need to use a Scala `Option` in your Java code, you can convert the `Option` to a Java `Optional` value using the `toJava` method of the Scala _scala.jdk.javaapi.OptionConverters_ object. +When you need to use a Scala `Option` in your Java code, you can convert the `Option` to a Java `Optional` value using the `toJava` method of the Scala `scala.jdk.javaapi.OptionConverters` object. To demonstrate this, create a Scala class with two `Option[String]` values, one containing a string and the other one empty: @@ -203,7 +202,7 @@ object ScalaObject: val noneString: Option[String] = None ``` -Then in your Java code, convert those `Option[String]` values into `java.util.Optional[String]` using the `toJava` method from the _scala.jdk.javaapi.OptionConverters_ object: +Then in your Java code, convert those `Option[String]` values into `java.util.Optional[String]` using the `toJava` method from the `scala.jdk.javaapi.OptionConverters` object: ```java // java @@ -258,7 +257,7 @@ System.out.println(jm.multiply(3,4)); // 12 ## How to handle Scala methods that throw exceptions in Java code When you’re writing Scala code using Scala programming idioms, you’ll never write a method that throws an exception. -But if for some reason you have a Scala method that does throw an exception, and you want Java developers to be able to use that method, add the `@throws` annotation to your Scala method so Java consumers will know the exceptions they can throw. +But if for some reason you have a Scala method that does throw an exception, and you want Java developers to be able to use that method, add the `@throws` annotation to your Scala method so Java consumers will know the exceptions it can throw. For example, this Scala `exceptionThrower` method is annotated to declare that it throws an `Exception`: diff --git a/_overviews/scala3-book/scala-for-java-devs.md b/_overviews/scala3-book/scala-for-java-devs.md index 50d1777677..be54f5fd25 100644 --- a/_overviews/scala3-book/scala-for-java-devs.md +++ b/_overviews/scala3-book/scala-for-java-devs.md @@ -49,6 +49,7 @@ Also at a high level, the differences between Java and Scala are: - Scala has a full suite of immutable collections, including `List`, `Vector`, and immutable `Map` and `Set` implementations - Everything in Scala is an _expression_: constructs like `if` statements, `for` loops, `match` expressions, and even `try`/`catch` expressions all have return values - Scala idioms favor immutability by default: you’re encouraged to use immutable (`final`) variables and immutable collections +- Idiomatic Scala code does not use `null`, and thus does not suffer from `NullPointerException` - The Scala ecosystem has other [build tools][tools] in sbt, Mill, and others - In addition to running on the JVM, the [Scala.js](https://www.scala-js.org) project lets you use Scala as a JavaScript replacement - The [Scala Native](http://www.scala-native.org) project adds low-level constructs to let you write “systems” level code, and also compiles to native executables @@ -117,14 +118,18 @@ This section provides comparisons of features related to OOP-style classes and m ### OOP style class, primary constructor: +Scala doesn’t follow the JavaBeans standard, so instead of showing Java +code written in the JavaBeans style, here we show Java code that is +equivalent to the Scala code that follows it. + @@ -976,7 +981,7 @@ val a = Array("a", "b") as being backed by this Java `String[]`: ```scala -String[] a = ["a", "b"] +String[] a = ["a", "b"]; ``` However, a Scala `Array` also has all of the functional methods you expect in a Scala collection, including `map` and `filter`: @@ -1275,7 +1280,7 @@ For more information on dealing with errors and exceptions in Scala, see the [Fu That concludes are comparison of the Java and Scala languages. -Currently there are other concepts in Scala which currently have no equal in Java 11. +There are other concepts in Scala which currently have no equal in Java 11. This includes: - Everything related to Scala’s [contextual abstractions][contextual] diff --git a/_overviews/scala3-book/scala-for-javascript-devs.md b/_overviews/scala3-book/scala-for-javascript-devs.md index 0237e0d63c..a577837e56 100644 --- a/_overviews/scala3-book/scala-for-javascript-devs.md +++ b/_overviews/scala3-book/scala-for-javascript-devs.md @@ -36,7 +36,7 @@ At a high level, Scala shares these similarities with JavaScript: - Both languages have similar `if` statements, `while` loops, and `for` loops - Starting [at this Scala.js page](https://www.scala-js.org/libraries/index.html), you’ll find dozens of libraries to support React, Angular, jQuery, and many other JavaScript and Scala libraries - JavaScript objects are mutable; Scala objects _can_ be mutable when writing in an imperative style -- Both JavaScript and Scala support _promises_ as a way of running asynchronous computations ([Scala concurrency][concurrency] uses futures and promises) +- Both JavaScript and Scala support _promises_ as a way of handling the result of asynchronous computations ([Scala concurrency][concurrency] uses futures and promises) ### High-level differences @@ -441,7 +441,7 @@ In both JavaScript and Scala, functions are objects, so their functionality is s @@ -474,7 +474,7 @@ In both JavaScript and Scala, functions are objects, so their functionality is s
class Person { -
  private String firstName; -
  private String lastName; -
  private int age; +
  public String firstName; +
  public String lastName; +
  public int age;
  public Person(
    String firstName,
    String lastName, int age @@ -160,9 +165,9 @@ This section provides comparisons of features related to OOP-style classes and m
public class Person { -
  private String firstName; -
  private String lastName; -
  private int age; +
  public String firstName; +
  public String lastName; +
  public int age;

  // primary constructor
  public Person( @@ -424,7 +429,7 @@ This section compares Java interfaces to Scala traits, including how classes ext
- class Dog extends Animal, HasLegs, HasTail + class Dog extends Animal implements HasLegs, HasTail
- // technically this is a “method,” not a function + // technically this is a method, not a function
def add(a: Int, b: Int) = a + b
add(2, 2)   // 4
In Scala, showing the `Int` return type is optional. -It’s _not_ shown in the `add` example and _is_ shown in the `addThenDouble` example, so you can see both approaches. +It’s _not_ shown in the `add` example and _is_ shown in the `addAndDouble` example, so you can see both approaches. @@ -1374,4 +1374,3 @@ There are other concepts in Scala which currently have no equivalent in JavaScri [union-types]: {% link _overviews/scala3-book/types-union.md %} - diff --git a/_overviews/scala3-book/scala-for-python-devs.md b/_overviews/scala3-book/scala-for-python-devs.md index 0934989d4e..395d7c450d 100644 --- a/_overviews/scala3-book/scala-for-python-devs.md +++ b/_overviews/scala3-book/scala-for-python-devs.md @@ -230,7 +230,7 @@ These examples demonstrate how to create variables in Python and Scala. -If a Scala field is going to be mutable, use `var` instead of `val` for variable assignment: +If a Scala field is going to be mutable, use `var` instead of `val` for variable definition: ```scala var x = 1 @@ -631,18 +631,14 @@ Scala also has `match` expressions. - x = [i*10 for i in range(1,4)] -
# x: [10,20,30]
+ xs = [i * 10 for i in range(1, 4)] +
# xs: [10,20,30]
- val x = -
  for -
    i <- 1 to 3 -
  yield -
    i * 10 -
// x: Vector(10, 20, 30)
+ val xs = for i <- 1 to 3 yield i * 10 +
// xs: Vector(10, 20, 30)
@@ -894,9 +890,7 @@ However, the default Scala map is _immutable_, and has a number of transformatio - for -
  (key,value) <- myMap -
do + for (key,value) <- myMap do
  println(key)
  println(value)
@@ -934,7 +928,7 @@ The Python set is similar to the _mutable_ Scala `Set` class. set = {1,2,1} -
# set: {1,2}
+
# set: {1,2}
@@ -1012,7 +1006,7 @@ Those lists are used in the following table, that shows how to apply mapping and - x = [i*10 for i in numbers] + x = [i * 10 for i in numbers] @@ -1034,7 +1028,9 @@ Those lists are used in the following table, that shows how to apply mapping and - val evens = numbers.filter(_ % 2 == 0) + val evens = numbers.filter(_ % 2 == 0) +
// or +
val evens = for i <- numbers if i % 2 == 0 yield i
@@ -1051,8 +1047,9 @@ Those lists are used in the following table, that shows how to apply mapping and - val x = numbers.filter(_ % 2 == 0) -
          .map(_ * 10)
+ val x = numbers.filter(_ % 2 == 0).map(_ * 10) +
// or +
val x = for i <- numbers if i % 2 == 0 yield i * 10
@@ -1064,8 +1061,7 @@ Those lists are used in the following table, that shows how to apply mapping and - def times_10(n): return n * 10 -
x = map(lambda x: x * 10, numbers)
+ x = map(lambda x: x * 10, numbers) diff --git a/_overviews/scala3-book/scala-tools.md b/_overviews/scala3-book/scala-tools.md index 81f7177515..75bb1f2c0d 100644 --- a/_overviews/scala3-book/scala-tools.md +++ b/_overviews/scala3-book/scala-tools.md @@ -22,7 +22,7 @@ We’ll start by showing how to use sbt to build your Scala projects, and then w ## Building Scala projects with sbt You can use several different tools to build your Scala projects, including Ant, Maven, Gradle, Mill, and more. -But a tool named _sbt_ was the first build tool that was specifically created for Scala, and these days it’s supported by [Lightbend](https://www.lightbend.com), the company that also maintains [Akka](https://akka.io), the [Play framework](https://www.playframework.com), the [Lagom framework](https://www.lagomframework.com), and more. +But a tool named _sbt_ was the first build tool that was specifically created for Scala. > To install sbt, see [its download page](https://www.scala-sbt.org/download.html) or our [Getting Started][getting_started] page. @@ -38,7 +38,20 @@ $ mkdir hello $ cd hello ``` -Then create a file named _build.sbt_ that contains this line: +In the directory `hello`, create a subdirectory `project`: + +```bash +$ mkdir project +``` + +Create a file named _build.properties_ in the directory `project`, with +the following content: + +```text +sbt.version=1.5.4 +``` + +Then create a file named _build.sbt_ in the project root directory that contains this line: ```scala scalaVersion := "{{ site.scala-3-version }}" @@ -51,6 +64,18 @@ Now create a file named something like _Hello.scala_---the first part of the nam ``` That’s all you have to do. + +You should have a project structure like the following: + +~~~ bash +$ tree +. +├── build.sbt +├── Hello.scala +└── project + └── build.properties +~~~ + Now run the project with this `sbt` command: ```bash @@ -61,7 +86,7 @@ You should see output that looks like this, including the `"Hello, world"` from ```bash $ sbt run -[info] welcome to sbt 1.4.4 (AdoptOpenJDK Java 11.x) +[info] welcome to sbt 1.5.4 (AdoptOpenJDK Java 11.x) [info] loading project definition from project ... [info] loading settings for project from build.sbt ... [info] compiling 1 Scala source to target/scala-3.0.0/classes ... @@ -70,7 +95,9 @@ Hello, world [success] Total time: 2 s ``` -When you look at your directory, you’ll see that sbt has created two directories named _project_ and _target_. +The sbt launcher---the `sbt` command-line tool---loads the version of sbt set in the file _project/build.properties_, which loads the version of the Scala compiler set in the file _build.sbt_, compiles the code in the file _Hello.scala_, and runs the resulting bytecode. + +When you look at your directory, you’ll see that sbt has a directory named _target_. These are working directories that sbt uses. As you can see, creating and running a little Scala project with sbt takes just a few simple steps. @@ -92,31 +119,34 @@ A nice benefit of that is that once you’re comfortable with its structure, it The first thing to know is that underneath the root directory of your project, sbt expects a directory structure that looks like this: -```bash -build.sbt -project/ -src/ --- main/ - |-- java/ - |-- resources/ - |-- scala/ -|-- test/ - |-- java/ - |-- resources/ - |-- scala/ -target/ +```text +. +├── build.sbt +├── project/ +│ └── build.properties +├── src/ +│ ├── main/ +│ │ ├── java/ +│ │ ├── resources/ +│ │ └── scala/ +│ └── test/ +│ ├── java/ +│ ├── resources/ +│ └── scala/ +└── target/ ``` You can also add a _lib_ directory under the root directory if you want to add unmanaged dependencies---JAR files---to your project. If you’re going to create a project that has Scala source code files and tests, but won’t be using any Java source code files, and doesn’t need any “resources”---such as embedded images, configuration files, etc.---this is all you really need under the _src_ directory: -```bash -src/ --- main/ - |-- scala/ -|-- test/ - |-- scala/ +```text +. +└── src/ + ├── main/ + │ └── scala/ + └── test/ + └── scala/ ``` @@ -284,11 +314,18 @@ As with the previous lesson, create an sbt project directory structure for a pro $ mkdir HelloScalaTest $ cd HelloScalaTest $ mkdir -p src/{main,test}/scala -$ mkdir project target +$ mkdir project ``` -### Creating the build.sbt file +### Creating the build.properties and build.sbt files + +Next, create a _build.properties_ file in the _project/_ subdirectory of your project +with this line: + +```text +sbt.version=1.5.4 +``` Next, create a _build.sbt_ file in the root directory of your project with these contents: @@ -298,7 +335,7 @@ version := "0.1" scalaVersion := "{{site.scala-3-version}}" libraryDependencies ++= Seq( - "org.scalatest" %% "scalatest" % "3.3.0-SNAP3" % Test + "org.scalatest" %% "scalatest" % "3.2.9" % Test ) ``` From 512f89eb3fbdd80305d56e186f3775a7c49621ce Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Mon, 28 Jun 2021 17:30:19 +0200 Subject: [PATCH 1539/3075] Clarify the recommended learning path via the MOOCs --- learn.md | 16 ++++++++++++++++ resources/images/learning-path.png | Bin 0 -> 42763 bytes 2 files changed, 16 insertions(+) create mode 100644 resources/images/learning-path.png diff --git a/learn.md b/learn.md index 19af2b78c9..797f193e3e 100644 --- a/learn.md +++ b/learn.md @@ -36,6 +36,8 @@ this course in the following video: +This course is also a good way to upgrade your Scala 2 knowledge to Scala 3. + After taking this course, you might be interested in improving your skills in specific areas by taking the courses [Parallel Programming], [Big Data Analysis with Scala and Spark], or [Programming Reactive Systems]. @@ -61,6 +63,20 @@ and Spark. teaches how to write responsive, scalable, and resilient systems with the library Akka. +### Scala Learning Path + +The diagram below summarizes the possible learning paths with our courses: + +![](/resources/images/learning-path.png) + +The “foundational” courses target programmers with no prior experience in Scala, whereas the “deepening” +courses aim at strengthening Scala programmers skills in a specific domain (such as parallel programming). + +We recommend starting with either Effective Programming in Scala, or Functional Programming Principles in +Scala followed by Functional Program Design. Then, you can complement your Scala skills by taking any +of the courses Programming Reactive Systems, Parallel Programming, or Big Data Analysis with Scala and Spark. +In case you take the Scala Specialization, you will end with the Scala Capstone Project. + ### Scala 2 Courses The above courses use Scala 3 (except the Spark courses). If needed, you can find diff --git a/resources/images/learning-path.png b/resources/images/learning-path.png new file mode 100644 index 0000000000000000000000000000000000000000..43e9d09631651ea12fc71a3cd9707a9f97e05da8 GIT binary patch literal 42763 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 Date: Mon, 28 Jun 2021 10:07:30 -0700 Subject: [PATCH 1540/3075] FAQ: Who's behind Scala? --- _overviews/FAQ/index.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/_overviews/FAQ/index.md b/_overviews/FAQ/index.md index ba0cce896d..1bf9ea5b7a 100644 --- a/_overviews/FAQ/index.md +++ b/_overviews/FAQ/index.md @@ -58,6 +58,10 @@ This is addressed on our [Community page](https://scala-lang.org/community/#scal In short, the only officially sanctioned place is the [scala/job-board room on Gitter](https://gitter.im/scala/job-board). +### Who's behind Scala? + +This is answered [on the community page](https://www.scala-lang.org/community/#whos-behind-scala). + ### Can I use the Scala logo? See [scala/scala-lang#1040](https://github.com/scala/scala-lang/issues/1040). From 9ffe4b9aff6443d9e789a89bf2c84a62be7a55e7 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Wed, 30 Jun 2021 11:18:07 +0200 Subject: [PATCH 1541/3075] Merge https://github.com/lampepfl/dotty/blob/master/docs/docs/usage/getting-started.md here MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - The part about scastie was already mentioned in our scala3/getting-started.md page - Copied the part about the giter8 templates into the Scala 3 book, - IDE support was covered in our getting-started page - Skipped “Standalone installation”, since the recommended way to install Scala 3 is to use `cs` - “Scala 3 for scripting” was already covered by scala3/book/taste-hello-world.md --- _overviews/scala3-book/scala-tools.md | 36 +++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/_overviews/scala3-book/scala-tools.md b/_overviews/scala3-book/scala-tools.md index 75bb1f2c0d..bffe1791dd 100644 --- a/_overviews/scala3-book/scala-tools.md +++ b/_overviews/scala3-book/scala-tools.md @@ -269,6 +269,42 @@ There, that’s much faster. If you type `help` at the sbt command prompt you’ll see a list of other commands you can run. But for now, just type `exit` (or press `CTRL-D`) to leave the sbt shell. +### Using project templates + +Manually creating the project structure can be tedious. Thankfully, sbt can create it for you, +based on a template. + +To create a Scala 3 project from a template, run the following command in a shell: + +~~~ +$ sbt new scala/scala3.g8 +~~~ + +Sbt will load the template, ask some questions, and create the project files in a subdirectory: + +~~~ +$ tree scala-3-project-template +scala-3-project-template +├── build.sbt +├── project +│ └── build.properties +├── README.md +└── src + ├── main + │ └── scala + │ └── Main.scala + └── test + └── scala + └── Test1.scala +~~~ + +> If you want to create a Scala 3 project that cross-compiles with Scala 2, use the template `scala/scala3-cross.g8`: +> +> ~~~ +> $ sbt new scala/scala3-cross.g8 +> ~~~ + +Learn more about `sbt new` and project templates in the [documentation of sbt](https://www.scala-sbt.org/1.x/docs/sbt-new-and-Templates.html#sbt+new+and+Templates). ### Other build tools for Scala From 446a51fb7d8b4f907f2325d1a5cc3affcdc1790f Mon Sep 17 00:00:00 2001 From: Nate Black Date: Wed, 30 Jun 2021 08:31:25 -0400 Subject: [PATCH 1542/3075] Removed 'do' line from the Scala 2 while section --- _overviews/scala3-book/taste-control-structures.md | 1 - 1 file changed, 1 deletion(-) diff --git a/_overviews/scala3-book/taste-control-structures.md b/_overviews/scala3-book/taste-control-structures.md index 5c30f73da4..520453481f 100644 --- a/_overviews/scala3-book/taste-control-structures.md +++ b/_overviews/scala3-book/taste-control-structures.md @@ -239,7 +239,6 @@ In Scala 2, the syntax was a bit different. The condition was surrounded by pare there was no `do` keyword: ```scala -while (x >= 0) do x = f(x) while (x >= 0) { x = f(x) } ``` From 9b8c42b8498c3f55d0d2ffcec9c8c02b0c3d4866 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Wed, 30 Jun 2021 15:06:16 +0200 Subject: [PATCH 1543/3075] Merge https://github.com/lampepfl/dotty/blob/master/docs/docs/usage/ide-support.md here MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Only added a mention of BSP - Skipped instructions in “importing the project using BSP using IntelliJ” because they are not working --- scala3/getting-started.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scala3/getting-started.md b/scala3/getting-started.md index b24836f764..c888285fb3 100644 --- a/scala3/getting-started.md +++ b/scala3/getting-started.md @@ -117,8 +117,9 @@ They both offer rich IDE features, but you can still use [many other editors.](h When prompted to do so, select _Import build_. >[Metals](https://scalameta.org/metals) is a “Scala language server” that provides support for writing Scala code in VS Code and other editors like [Atom, Sublime Text, and more](https://scalameta.org/metals/docs/editors/overview.html), using the Language Server Protocol. -(For details on how Metals works, see, [“Write Scala in VS Code, Vim, Emacs, Atom and Sublime Text with Metals”](https://www.scala-lang.org/2019/04/16/metals.html).) - +> +> Under the hood, Metals communicates with the build tool by using +> the [Build Server Protocol (BSP)](https://build-server-protocol.github.io/). For details on how Metals works, see, [“Write Scala in VS Code, Vim, Emacs, Atom and Sublime Text with Metals”](https://www.scala-lang.org/2019/04/16/metals.html). ### View the source code From 3d941d96c703c12d4c8732ae5306530b5c7239d5 Mon Sep 17 00:00:00 2001 From: Adrien Piquerez Date: Wed, 30 Jun 2021 15:17:52 +0200 Subject: [PATCH 1544/3075] Fix page number --- _overviews/scala3-migration/external-resources.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-migration/external-resources.md b/_overviews/scala3-migration/external-resources.md index 77a65829b2..4915537176 100644 --- a/_overviews/scala3-migration/external-resources.md +++ b/_overviews/scala3-migration/external-resources.md @@ -2,7 +2,7 @@ title: External Resources type: section description: This section lists external resources about the migration to Scala 3. -num: 26 +num: 27 previous-page: plugin-kind-projector next-page: --- From 01b5a7cfff1ae96a9c2b9d1918df4f9e66fc2b5c Mon Sep 17 00:00:00 2001 From: Adrian Theodorescu Date: Sat, 3 Jul 2021 13:49:48 -0500 Subject: [PATCH 1545/3075] Fix typo in overviews/scala-book/scala-build-tool-sbt --- _overviews/scala-book/scala-build-tool-sbt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala-book/scala-build-tool-sbt.md b/_overviews/scala-book/scala-build-tool-sbt.md index e798bc05d2..8986433976 100644 --- a/_overviews/scala-book/scala-build-tool-sbt.md +++ b/_overviews/scala-book/scala-build-tool-sbt.md @@ -156,7 +156,7 @@ If you type `help` at the sbt command prompt you’ll see a bunch of other comma ## See also -Here’s a list of other build tools you can use to build Scala projects are: +Here’s a list of other build tools you can use to build Scala projects: - [Ant](http://ant.apache.org/) - [Gradle](https://gradle.org/) From 1b0bd33313fa592a65bec9731a85d9425ebf4c56 Mon Sep 17 00:00:00 2001 From: Genghis Yang Date: Sun, 4 Jul 2021 17:26:13 +0800 Subject: [PATCH 1546/3075] Remove duplicated `a` --- _overviews/scala3-book/fp-functions-are-values.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-book/fp-functions-are-values.md b/_overviews/scala3-book/fp-functions-are-values.md index 0c8a1df792..d2766c65fe 100644 --- a/_overviews/scala3-book/fp-functions-are-values.md +++ b/_overviews/scala3-book/fp-functions-are-values.md @@ -37,7 +37,7 @@ val doubles = nums.filter(underFive).map(double) This ability to treat methods and functions as values is a powerful feature that functional programming languages provide. -> Technically, a a function that takes another function as an input parameter is known as a *Higher-Order Function*. +> Technically, a function that takes another function as an input parameter is known as a *Higher-Order Function*. > (If you like humor, as someone once wrote, that’s like saying that a class that takes an instance of another class as a constructor parameter is a Higher-Order Class.) From bf9f32e844c577d1d4ba55a5f7fe31ffd11a4300 Mon Sep 17 00:00:00 2001 From: Haythem Chagwey Date: Sun, 4 Jul 2021 10:48:27 +0100 Subject: [PATCH 1547/3075] Update the Type inference section's link --- _overviews/scala3-book/scala-features.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-book/scala-features.md b/_overviews/scala3-book/scala-features.md index f0c8efb129..606365a130 100644 --- a/_overviews/scala3-book/scala-features.md +++ b/_overviews/scala3-book/scala-features.md @@ -161,7 +161,7 @@ In that list: Scala’s type system enforces, at compile-time, that abstractions are used in a safe and coherent manner. In particular, the type system supports: -- [Type inference](/tour/type-inference.html) +- [Inferred types]({% link _overviews/scala3-book/types-inferred.md %}) - [Generic classes]({% link _overviews/scala3-book/types-generics.md %}) - [Variance annotations]({% link _overviews/scala3-book/types-variance.md %}) - [Upper](/tour/upper-type-bounds.html) and [lower](/tour/lower-type-bounds.html) type bounds From 45678020ba4566d9d8cf8562a39827c7d1dbe34a Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Mon, 5 Jul 2021 14:36:41 +0200 Subject: [PATCH 1548/3075] Introduce a page about worksheets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, the page “Scala Tools” was mainly about sbt. We now have a chapter “Scala Tools”, which contains two sections: “Building and Testing Scala Projects with sbt”, and “Worksheets”. --- .../scala3-book/interacting-with-java.md | 4 +- _overviews/scala3-book/scala-for-java-devs.md | 2 +- .../scala3-book/scala-for-javascript-devs.md | 2 +- .../scala3-book/scala-for-python-devs.md | 2 +- _overviews/scala3-book/scala-tools.md | 508 +---------------- _overviews/scala3-book/taste-repl.md | 2 + _overviews/scala3-book/tools-sbt.md | 512 ++++++++++++++++++ _overviews/scala3-book/tools-worksheets.md | 56 ++ .../images/scala3-book/intellij-worksheet.png | Bin 0 -> 12899 bytes .../images/scala3-book/metals-worksheet.png | Bin 0 -> 16233 bytes 10 files changed, 579 insertions(+), 509 deletions(-) create mode 100644 _overviews/scala3-book/tools-sbt.md create mode 100644 _overviews/scala3-book/tools-worksheets.md create mode 100644 resources/images/scala3-book/intellij-worksheet.png create mode 100644 resources/images/scala3-book/metals-worksheet.png diff --git a/_overviews/scala3-book/interacting-with-java.md b/_overviews/scala3-book/interacting-with-java.md index 8ccb38e156..5b0b99286b 100644 --- a/_overviews/scala3-book/interacting-with-java.md +++ b/_overviews/scala3-book/interacting-with-java.md @@ -2,8 +2,8 @@ title: Interacting with Java type: chapter description: This page demonstrates how Scala code can interact with Java, and how Java code can interact with Scala code. -num: 70 -previous-page: scala-tools +num: 72 +previous-page: tools-worksheets next-page: scala-for-java-devs --- diff --git a/_overviews/scala3-book/scala-for-java-devs.md b/_overviews/scala3-book/scala-for-java-devs.md index be54f5fd25..125f77c06e 100644 --- a/_overviews/scala3-book/scala-for-java-devs.md +++ b/_overviews/scala3-book/scala-for-java-devs.md @@ -2,7 +2,7 @@ title: Scala for Java Developers type: chapter description: This page is for Java developers who are interested in learning about Scala 3. -num: 71 +num: 73 previous-page: interacting-with-java next-page: scala-for-javascript-devs --- diff --git a/_overviews/scala3-book/scala-for-javascript-devs.md b/_overviews/scala3-book/scala-for-javascript-devs.md index a577837e56..462a1017ce 100644 --- a/_overviews/scala3-book/scala-for-javascript-devs.md +++ b/_overviews/scala3-book/scala-for-javascript-devs.md @@ -2,7 +2,7 @@ title: Scala for JavaScript Developers type: chapter description: This chapter provides an introduction to Scala 3 for JavaScript developers -num: 72 +num: 74 previous-page: scala-for-java-devs next-page: scala-for-python-devs --- diff --git a/_overviews/scala3-book/scala-for-python-devs.md b/_overviews/scala3-book/scala-for-python-devs.md index 395d7c450d..77fb3c5881 100644 --- a/_overviews/scala3-book/scala-for-python-devs.md +++ b/_overviews/scala3-book/scala-for-python-devs.md @@ -2,7 +2,7 @@ title: Scala for Python Developers type: chapter description: This page is for Python developers who are interested in learning about Scala 3. -num: 73 +num: 75 previous-page: scala-for-javascript-devs next-page: --- diff --git a/_overviews/scala3-book/scala-tools.md b/_overviews/scala3-book/scala-tools.md index bffe1791dd..52e4bc67b7 100644 --- a/_overviews/scala3-book/scala-tools.md +++ b/_overviews/scala3-book/scala-tools.md @@ -4,510 +4,10 @@ type: chapter description: This chapter looks at two commonly-used Scala tools, sbt and ScalaTest. num: 69 previous-page: concurrency -next-page: interacting-with-java +next-page: tools-sbt --- +This chapter introduces two ways to write and run Scala programs: -In this chapter you’ll see two tools that are commonly used in Scala projects: - -- The [sbt](https://www.scala-sbt.org) build tool -- [ScalaTest](https://www.scalatest.org), a source code testing framework - -We’ll start by showing how to use sbt to build your Scala projects, and then we’ll show how to use sbt and ScalaTest together to test your Scala projects. - -> If you want to learn about tools to help you migrate your Scala 2 code to Scala 3, see our [Scala 3 Migration Guide](/scala3/guides/migration/compatibility-intro.html). - - - -## Building Scala projects with sbt - -You can use several different tools to build your Scala projects, including Ant, Maven, Gradle, Mill, and more. -But a tool named _sbt_ was the first build tool that was specifically created for Scala. - -> To install sbt, see [its download page](https://www.scala-sbt.org/download.html) or our [Getting Started][getting_started] page. - - - -### Creating a “Hello, world” project - -You can create an sbt “Hello, world” project in just a few steps. -First, create a directory to work in, and move into that directory: - -```bash -$ mkdir hello -$ cd hello -``` - -In the directory `hello`, create a subdirectory `project`: - -```bash -$ mkdir project -``` - -Create a file named _build.properties_ in the directory `project`, with -the following content: - -```text -sbt.version=1.5.4 -``` - -Then create a file named _build.sbt_ in the project root directory that contains this line: - -```scala -scalaVersion := "{{ site.scala-3-version }}" -``` - -Now create a file named something like _Hello.scala_---the first part of the name doesn’t matter---with this line: - -```scala -@main def helloWorld = println("Hello, world") -``` - -That’s all you have to do. - -You should have a project structure like the following: - -~~~ bash -$ tree -. -├── build.sbt -├── Hello.scala -└── project - └── build.properties -~~~ - -Now run the project with this `sbt` command: - -```bash -$ sbt run -``` - -You should see output that looks like this, including the `"Hello, world"` from your program: - -```bash -$ sbt run -[info] welcome to sbt 1.5.4 (AdoptOpenJDK Java 11.x) -[info] loading project definition from project ... -[info] loading settings for project from build.sbt ... -[info] compiling 1 Scala source to target/scala-3.0.0/classes ... -[info] running helloWorld -Hello, world -[success] Total time: 2 s -``` - -The sbt launcher---the `sbt` command-line tool---loads the version of sbt set in the file _project/build.properties_, which loads the version of the Scala compiler set in the file _build.sbt_, compiles the code in the file _Hello.scala_, and runs the resulting bytecode. - -When you look at your directory, you’ll see that sbt has a directory named _target_. -These are working directories that sbt uses. - -As you can see, creating and running a little Scala project with sbt takes just a few simple steps. - -> For sbt version < 1.5.0, it is required to have the following line in a *project/plugins.sbt* file: `addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "{{ site.scala-3-plugin-version }}")` - - -### Using sbt with larger projects - -For a little project, that’s all that sbt requires to run. -For larger projects that require many source code files, dependencies, or sbt plugins, you’ll want to create an organized directory structure. -The rest of this section demonstrates the structure that sbt uses. - - -### The sbt directory structure - -Like Maven, sbt uses a standard project directory structure. -A nice benefit of that is that once you’re comfortable with its structure, it makes it easy to work on other Scala/sbt projects. - -The first thing to know is that underneath the root directory of your project, sbt expects a directory structure that looks like this: - -```text -. -├── build.sbt -├── project/ -│ └── build.properties -├── src/ -│ ├── main/ -│ │ ├── java/ -│ │ ├── resources/ -│ │ └── scala/ -│ └── test/ -│ ├── java/ -│ ├── resources/ -│ └── scala/ -└── target/ -``` - -You can also add a _lib_ directory under the root directory if you want to add unmanaged dependencies---JAR files---to your project. - -If you’re going to create a project that has Scala source code files and tests, but won’t be using any Java source code files, and doesn’t need any “resources”---such as embedded images, configuration files, etc.---this is all you really need under the _src_ directory: - -```text -. -└── src/ - ├── main/ - │ └── scala/ - └── test/ - └── scala/ -``` - - -### “Hello, world” with an sbt directory structure - -{% comment %} -LATER: using something like `sbt new scala/scala3.g8` may eventually - be preferable, but that seems to have a few bugs atm (creates - a 'target' directory above the root; renames the root dir; - uses 'dottyVersion'; 'name' doesn’t match the supplied name; - config syntax is a little hard for beginners.) -{% endcomment %} - -Creating this directory structure is simple. -There are tools to do this for you, but assuming that you’re using a Unix/Linux system, you can use these commands to create your first sbt project directory structure: - -```bash -$ mkdir HelloWorld -$ cd HelloWorld -$ mkdir -p src/{main,test}/scala -$ mkdir project target -``` - -When you run a `find .` command after running those commands, you should see this result: - -```bash -$ find . -. -./project -./src -./src/main -./src/main/scala -./src/test -./src/test/scala -./target -``` - -If you see that, you’re in great shape for the next step. - -> There are other ways to create the files and directories for an sbt project. -> One way is to use the `sbt new` command, [which is documented here on scala-sbt.org](https://www.scala-sbt.org/1.x/docs/Hello.html). -> That approach isn’t shown here because some of the files it creates are more complicated than necessary for an introduction like this. - - -### Creating a first build.sbt file - -At this point you only need two more things to run a “Hello, world” project: - -- A _build.sbt_ file -- A _Hello.scala_ file - -For a little project like this, the _build.sbt_ file only needs a `scalaVersion` entry, but we’ll add three lines that you commonly see: - -```scala -name := "HelloWorld" -version := "0.1" -scalaVersion := "{{ site.scala-3-version }}" -``` - -Because sbt projects use a standard directory structure, sbt can find everything else it needs. - -Now you just need to add a little “Hello, world” program. - - -### A “Hello, world” program - -In large projects, all of your Scala source code files will go under the _src/main/scala_ and _src/test/scala_ directories, but for a little sample project like this, you can put your source code file in the root directory of your project. -Therefore, create a file named _HelloWorld.scala_ in the root directory with these contents: - -```scala -@main def helloWorld = println("Hello, world") -``` - -That code defines a Scala 3 “main” method that prints the `"Hello, world"` when it’s run. - -Now, use the `sbt run` command to compile and run your project: - -```bash -$ sbt run - -[info] welcome to sbt -[info] loading settings for project ... -[info] loading project definition -[info] loading settings for project root from build.sbt ... -[info] Compiling 1 Scala source ... -[info] running helloWorld -Hello, world -[success] Total time: 4 s -``` - -The first time you run `sbt` it downloads everything it needs, and that can take a few moments to run, but after that it gets much faster. - -Also, once you get this first step working, you’ll find that it’s much faster to run sbt interactively. -To do that, first run the `sbt` command by itself: - -```bash -$ sbt - -[info] welcome to sbt -[info] loading settings for project ... -[info] loading project definition ... -[info] loading settings for project root from build.sbt ... -[info] sbt server started at - local:///${HOME}/.sbt/1.0/server/7d26bae822c36a31071c/sock -sbt:hello-world> _ -``` - -Then inside this sbt shell, execute its `run` command: - -```` -sbt:hello-world> run - -[info] running helloWorld -Hello, world -[success] Total time: 0 s -```` - -There, that’s much faster. - -If you type `help` at the sbt command prompt you’ll see a list of other commands you can run. -But for now, just type `exit` (or press `CTRL-D`) to leave the sbt shell. - -### Using project templates - -Manually creating the project structure can be tedious. Thankfully, sbt can create it for you, -based on a template. - -To create a Scala 3 project from a template, run the following command in a shell: - -~~~ -$ sbt new scala/scala3.g8 -~~~ - -Sbt will load the template, ask some questions, and create the project files in a subdirectory: - -~~~ -$ tree scala-3-project-template -scala-3-project-template -├── build.sbt -├── project -│ └── build.properties -├── README.md -└── src - ├── main - │ └── scala - │ └── Main.scala - └── test - └── scala - └── Test1.scala -~~~ - -> If you want to create a Scala 3 project that cross-compiles with Scala 2, use the template `scala/scala3-cross.g8`: -> -> ~~~ -> $ sbt new scala/scala3-cross.g8 -> ~~~ - -Learn more about `sbt new` and project templates in the [documentation of sbt](https://www.scala-sbt.org/1.x/docs/sbt-new-and-Templates.html#sbt+new+and+Templates). - -### Other build tools for Scala - -While sbt is widely used, there are other tools you can use to build Scala projects: - -- [Ant](https://ant.apache.org/) -- [Gradle](https://gradle.org/) -- [Maven](https://maven.apache.org/) -- [Mill](https://com-lihaoyi.github.io/mill/) - -#### Coursier - -In a related note, [Coursier](https://get-coursier.io/docs/overview) is a “dependency resolver,” similar to Maven and Ivy in function. -It’s written from scratch in Scala, “embraces functional programming principles,” and downloads artifacts in parallel for rapid downloads. -sbt uses it to handle most dependency resolutions, and as a command-line tool, it can be used to easily install tools like sbt, Java, and Scala on your system, as shown in our [Getting Started][getting_started] page. - -This example from the `launch` web page shows that the `cs launch` command can be used to launch applications from dependencies: - -```scala -$ cs launch org.scalameta::scalafmt-cli:2.4.2 -- --help -scalafmt 2.4.2 -Usage: scalafmt [options] [...] - - -h, --help prints this usage text - -v, --version print version - more ... -``` - -See Coursier’s [launch page](https://get-coursier.io/docs/cli-launch) for more details. - - - -## Using sbt with ScalaTest - -[ScalaTest](https://www.scalatest.org) is one of the main testing libraries for Scala projects, and in this section you’ll see how to create a Scala/sbt project that uses ScalaTest. - - -### Creating the project directory structure - -As with the previous lesson, create an sbt project directory structure for a project named _HelloScalaTest_ with the following commands: - -```bash -$ mkdir HelloScalaTest -$ cd HelloScalaTest -$ mkdir -p src/{main,test}/scala -$ mkdir project -``` - - -### Creating the build.properties and build.sbt files - -Next, create a _build.properties_ file in the _project/_ subdirectory of your project -with this line: - -```text -sbt.version=1.5.4 -``` - -Next, create a _build.sbt_ file in the root directory of your project with these contents: - -```scala -name := "HelloScalaTest" -version := "0.1" -scalaVersion := "{{site.scala-3-version}}" - -libraryDependencies ++= Seq( - "org.scalatest" %% "scalatest" % "3.2.9" % Test -) -``` - -The first three lines of this file are essentially the same as the first example. -The `libraryDependencies` lines tell sbt to include the dependencies (JAR files) that are needed to include ScalaTest. - -> The ScalaTest documentation has always been good, and you can always find the up to date information on what those lines should look like on the [Installing ScalaTest](https://www.scalatest.org/install) page. - - -### Create a Scala source code file - -Next, create a Scala program that you can use to demonstrate ScalaTest. -First, create a directory under _src/main/scala_ named _math_: - -```bash -$ mkdir src/main/scala/math - ---- -``` - -Then, inside that directory, create a file named _MathUtils.scala_ with these contents: - -```scala -package math - -object MathUtils: - def double(i: Int) = i * 2 -``` - -That method provides a simple way to demonstrate ScalaTest. - - -{% comment %} -Because this project doesn’t have a `main` method, we don’t try to run it with `sbt run`; we just compile it with `sbt compile`: - -```` -$ sbt compile - -[info] welcome to sbt -[info] loading settings for project ... -[info] loading project definition ... -[info] loading settings for project ... -[info] Executing in batch mode. For better performance use sbt's shell -[success] Total time: 1 s -```` - -With that compiled, let’s create a ScalaTest file to test the `double` method. -{% endcomment %} - - -### Your first ScalaTest tests - -ScalaTest is very flexible, and offers several different ways to write tests. -A simple way to get started is to write tests using the ScalaTest `AnyFunSuite`. -To get started, create a directory named _math_ under the _src/test/scala_ directory: - -```bash -$ mkdir src/test/scala/math - ---- -``` - -Next, create a file named _MathUtilsTests.scala_ in that directory with the following contents: - -```scala -package math - -import org.scalatest.funsuite.AnyFunSuite - -class MathUtilsTests extends AnyFunSuite: - - // test 1 - test("'double' should handle 0") { - val result = MathUtils.double(0) - assert(result == 0) - } - - // test 2 - test("'double' should handle 1") { - val result = MathUtils.double(1) - assert(result == 2) - } - - test("test with Int.MaxValue") (pending) - -end MathUtilsTests -``` - -This code demonstrates the ScalaTest `AnyFunSuite` approach. -A few important points: - -- Your test class should extend `AnyFunSuite` -- You create tests as shown, by giving each `test` a unique name -- At the end of each test you should call `assert` to test that a condition has been satisfied -- When you know you want to write a test, but you don’t want to write it right now, create the test as “pending,” with the syntax shown - -Using ScalaTest like this is similar to JUnit, so if you’re coming to Scala from Java, hopefully this looks similar. - -Now you can run these tests with the `sbt test` command. -Skipping the first few lines of output, the result looks like this: - -```` -sbt:HelloScalaTest> test - -[info] Compiling 1 Scala source ... -[info] MathUtilsTests: -[info] - 'double' should handle 0 -[info] - 'double' should handle 1 -[info] - test with Int.MaxValue (pending) -[info] Total number of tests run: 2 -[info] Suites: completed 1, aborted 0 -[info] Tests: succeeded 2, failed 0, canceled 0, ignored 0, pending 1 -[info] All tests passed. -[success] Total time: 1 s -```` - -If everything works well, you’ll see output that looks like that. -Welcome to the world of testing Scala applications with sbt and ScalaTest. - - -### Support for many types of tests - -This example demonstrates a style of testing that’s similar to xUnit _Test-Driven Development_ (TDD) style testing, with a few benefits of the _Behavior-Driven Development_ (BDD) style. - -As mentioned, ScalaTest is flexible and you can also write tests using other styles, such as a style similar to Ruby’s RSpec. -You can also use mock objects, property-based testing, and use ScalaTest to test Scala.js code. - -See the User Guide on the [ScalaTest website](https://www.scalatest.org) for more details on the different testing styles that are available. - - - -## Where to go from here - -For more information about sbt and ScalaTest, see the following resources: - -- [The sbt documentation](https://www.scala-sbt.org/1.x/docs/) -- [The ScalaTest website](https://www.scalatest.org/) - - - -[getting_started]: {{ site.baseurl }}/scala3/getting-started.html +- by creating Scala projects, possibly containing multiple files, and defining a program entry point, +- by interacting with a worksheet, which is a program defined in a single file, executed line by line. diff --git a/_overviews/scala3-book/taste-repl.md b/_overviews/scala3-book/taste-repl.md index 130168c5cb..dba5420401 100644 --- a/_overviews/scala3-book/taste-repl.md +++ b/_overviews/scala3-book/taste-repl.md @@ -54,4 +54,6 @@ val res2: Int = 4 If you prefer a browser-based playground environment, you can also use [scastie.scala-lang.org](https://scastie.scala-lang.org). +If you prefer writing your code in a text editor instead of in console prompt, you can use a [worksheet]. +[worksheet]: {% link _overviews/scala3-book/tools-worksheets.md %} diff --git a/_overviews/scala3-book/tools-sbt.md b/_overviews/scala3-book/tools-sbt.md new file mode 100644 index 0000000000..e5dd291293 --- /dev/null +++ b/_overviews/scala3-book/tools-sbt.md @@ -0,0 +1,512 @@ +--- +title: Building and Testing Scala Projects with sbt +type: section +description: This section looks at a commonly-used build tool, sbt, and a testing library, ScalaTest. +num: 70 +previous-page: scala-tools +next-page: tools-worksheets +--- + +In this section you’ll see two tools that are commonly used in Scala projects: + +- The [sbt](https://www.scala-sbt.org) build tool +- [ScalaTest](https://www.scalatest.org), a source code testing framework + +We’ll start by showing how to use sbt to build your Scala projects, and then we’ll show how to use sbt and ScalaTest together to test your Scala projects. + +> If you want to learn about tools to help you migrate your Scala 2 code to Scala 3, see our [Scala 3 Migration Guide](/scala3/guides/migration/compatibility-intro.html). + + + +## Building Scala projects with sbt + +You can use several different tools to build your Scala projects, including Ant, Maven, Gradle, Mill, and more. +But a tool named _sbt_ was the first build tool that was specifically created for Scala. + +> To install sbt, see [its download page](https://www.scala-sbt.org/download.html) or our [Getting Started][getting_started] page. + + + +### Creating a “Hello, world” project + +You can create an sbt “Hello, world” project in just a few steps. +First, create a directory to work in, and move into that directory: + +```bash +$ mkdir hello +$ cd hello +``` + +In the directory `hello`, create a subdirectory `project`: + +```bash +$ mkdir project +``` + +Create a file named _build.properties_ in the directory `project`, with +the following content: + +```text +sbt.version=1.5.4 +``` + +Then create a file named _build.sbt_ in the project root directory that contains this line: + +```scala +scalaVersion := "{{ site.scala-3-version }}" +``` + +Now create a file named something like _Hello.scala_---the first part of the name doesn’t matter---with this line: + +```scala +@main def helloWorld = println("Hello, world") +``` + +That’s all you have to do. + +You should have a project structure like the following: + +~~~ bash +$ tree +. +├── build.sbt +├── Hello.scala +└── project + └── build.properties +~~~ + +Now run the project with this `sbt` command: + +```bash +$ sbt run +``` + +You should see output that looks like this, including the `"Hello, world"` from your program: + +```bash +$ sbt run +[info] welcome to sbt 1.5.4 (AdoptOpenJDK Java 11.x) +[info] loading project definition from project ... +[info] loading settings for project from build.sbt ... +[info] compiling 1 Scala source to target/scala-3.0.0/classes ... +[info] running helloWorld +Hello, world +[success] Total time: 2 s +``` + +The sbt launcher---the `sbt` command-line tool---loads the version of sbt set in the file _project/build.properties_, which loads the version of the Scala compiler set in the file _build.sbt_, compiles the code in the file _Hello.scala_, and runs the resulting bytecode. + +When you look at your directory, you’ll see that sbt has a directory named _target_. +These are working directories that sbt uses. + +As you can see, creating and running a little Scala project with sbt takes just a few simple steps. + +> For sbt version < 1.5.0, it is required to have the following line in a *project/plugins.sbt* file: `addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "{{ site.scala-3-plugin-version }}")` + + +### Using sbt with larger projects + +For a little project, that’s all that sbt requires to run. +For larger projects that require many source code files, dependencies, or sbt plugins, you’ll want to create an organized directory structure. +The rest of this section demonstrates the structure that sbt uses. + + +### The sbt directory structure + +Like Maven, sbt uses a standard project directory structure. +A nice benefit of that is that once you’re comfortable with its structure, it makes it easy to work on other Scala/sbt projects. + +The first thing to know is that underneath the root directory of your project, sbt expects a directory structure that looks like this: + +```text +. +├── build.sbt +├── project/ +│ └── build.properties +├── src/ +│ ├── main/ +│ │ ├── java/ +│ │ ├── resources/ +│ │ └── scala/ +│ └── test/ +│ ├── java/ +│ ├── resources/ +│ └── scala/ +└── target/ +``` + +You can also add a _lib_ directory under the root directory if you want to add unmanaged dependencies---JAR files---to your project. + +If you’re going to create a project that has Scala source code files and tests, but won’t be using any Java source code files, and doesn’t need any “resources”---such as embedded images, configuration files, etc.---this is all you really need under the _src_ directory: + +```text +. +└── src/ + ├── main/ + │ └── scala/ + └── test/ + └── scala/ +``` + + +### “Hello, world” with an sbt directory structure + +{% comment %} +LATER: using something like `sbt new scala/scala3.g8` may eventually + be preferable, but that seems to have a few bugs atm (creates + a 'target' directory above the root; renames the root dir; + uses 'dottyVersion'; 'name' doesn’t match the supplied name; + config syntax is a little hard for beginners.) +{% endcomment %} + +Creating this directory structure is simple. +There are tools to do this for you, but assuming that you’re using a Unix/Linux system, you can use these commands to create your first sbt project directory structure: + +```bash +$ mkdir HelloWorld +$ cd HelloWorld +$ mkdir -p src/{main,test}/scala +$ mkdir project target +``` + +When you run a `find .` command after running those commands, you should see this result: + +```bash +$ find . +. +./project +./src +./src/main +./src/main/scala +./src/test +./src/test/scala +./target +``` + +If you see that, you’re in great shape for the next step. + +> There are other ways to create the files and directories for an sbt project. +> One way is to use the `sbt new` command, [which is documented here on scala-sbt.org](https://www.scala-sbt.org/1.x/docs/Hello.html). +> That approach isn’t shown here because some of the files it creates are more complicated than necessary for an introduction like this. + + +### Creating a first build.sbt file + +At this point you only need two more things to run a “Hello, world” project: + +- A _build.sbt_ file +- A _Hello.scala_ file + +For a little project like this, the _build.sbt_ file only needs a `scalaVersion` entry, but we’ll add three lines that you commonly see: + +```scala +name := "HelloWorld" +version := "0.1" +scalaVersion := "{{ site.scala-3-version }}" +``` + +Because sbt projects use a standard directory structure, sbt can find everything else it needs. + +Now you just need to add a little “Hello, world” program. + + +### A “Hello, world” program + +In large projects, all of your Scala source code files will go under the _src/main/scala_ and _src/test/scala_ directories, but for a little sample project like this, you can put your source code file in the root directory of your project. +Therefore, create a file named _HelloWorld.scala_ in the root directory with these contents: + +```scala +@main def helloWorld = println("Hello, world") +``` + +That code defines a Scala 3 “main” method that prints the `"Hello, world"` when it’s run. + +Now, use the `sbt run` command to compile and run your project: + +```bash +$ sbt run + +[info] welcome to sbt +[info] loading settings for project ... +[info] loading project definition +[info] loading settings for project root from build.sbt ... +[info] Compiling 1 Scala source ... +[info] running helloWorld +Hello, world +[success] Total time: 4 s +``` + +The first time you run `sbt` it downloads everything it needs, and that can take a few moments to run, but after that it gets much faster. + +Also, once you get this first step working, you’ll find that it’s much faster to run sbt interactively. +To do that, first run the `sbt` command by itself: + +```bash +$ sbt + +[info] welcome to sbt +[info] loading settings for project ... +[info] loading project definition ... +[info] loading settings for project root from build.sbt ... +[info] sbt server started at + local:///${HOME}/.sbt/1.0/server/7d26bae822c36a31071c/sock +sbt:hello-world> _ +``` + +Then inside this sbt shell, execute its `run` command: + +```` +sbt:hello-world> run + +[info] running helloWorld +Hello, world +[success] Total time: 0 s +```` + +There, that’s much faster. + +If you type `help` at the sbt command prompt you’ll see a list of other commands you can run. +But for now, just type `exit` (or press `CTRL-D`) to leave the sbt shell. + +### Using project templates + +Manually creating the project structure can be tedious. Thankfully, sbt can create it for you, +based on a template. + +To create a Scala 3 project from a template, run the following command in a shell: + +~~~ +$ sbt new scala/scala3.g8 +~~~ + +Sbt will load the template, ask some questions, and create the project files in a subdirectory: + +~~~ +$ tree scala-3-project-template +scala-3-project-template +├── build.sbt +├── project +│ └── build.properties +├── README.md +└── src + ├── main + │ └── scala + │ └── Main.scala + └── test + └── scala + └── Test1.scala +~~~ + +> If you want to create a Scala 3 project that cross-compiles with Scala 2, use the template `scala/scala3-cross.g8`: +> +> ~~~ +> $ sbt new scala/scala3-cross.g8 +> ~~~ + +Learn more about `sbt new` and project templates in the [documentation of sbt](https://www.scala-sbt.org/1.x/docs/sbt-new-and-Templates.html#sbt+new+and+Templates). + +### Other build tools for Scala + +While sbt is widely used, there are other tools you can use to build Scala projects: + +- [Ant](https://ant.apache.org/) +- [Gradle](https://gradle.org/) +- [Maven](https://maven.apache.org/) +- [Mill](https://com-lihaoyi.github.io/mill/) + +#### Coursier + +In a related note, [Coursier](https://get-coursier.io/docs/overview) is a “dependency resolver,” similar to Maven and Ivy in function. +It’s written from scratch in Scala, “embraces functional programming principles,” and downloads artifacts in parallel for rapid downloads. +sbt uses it to handle most dependency resolutions, and as a command-line tool, it can be used to easily install tools like sbt, Java, and Scala on your system, as shown in our [Getting Started][getting_started] page. + +This example from the `launch` web page shows that the `cs launch` command can be used to launch applications from dependencies: + +```scala +$ cs launch org.scalameta::scalafmt-cli:2.4.2 -- --help +scalafmt 2.4.2 +Usage: scalafmt [options] [...] + + -h, --help prints this usage text + -v, --version print version + more ... +``` + +See Coursier’s [launch page](https://get-coursier.io/docs/cli-launch) for more details. + + + +## Using sbt with ScalaTest + +[ScalaTest](https://www.scalatest.org) is one of the main testing libraries for Scala projects, and in this section you’ll see how to create a Scala/sbt project that uses ScalaTest. + + +### Creating the project directory structure + +As with the previous lesson, create an sbt project directory structure for a project named _HelloScalaTest_ with the following commands: + +```bash +$ mkdir HelloScalaTest +$ cd HelloScalaTest +$ mkdir -p src/{main,test}/scala +$ mkdir project +``` + + +### Creating the build.properties and build.sbt files + +Next, create a _build.properties_ file in the _project/_ subdirectory of your project +with this line: + +```text +sbt.version=1.5.4 +``` + +Next, create a _build.sbt_ file in the root directory of your project with these contents: + +```scala +name := "HelloScalaTest" +version := "0.1" +scalaVersion := "{{site.scala-3-version}}" + +libraryDependencies ++= Seq( + "org.scalatest" %% "scalatest" % "3.2.9" % Test +) +``` + +The first three lines of this file are essentially the same as the first example. +The `libraryDependencies` lines tell sbt to include the dependencies (JAR files) that are needed to include ScalaTest. + +> The ScalaTest documentation has always been good, and you can always find the up to date information on what those lines should look like on the [Installing ScalaTest](https://www.scalatest.org/install) page. + + +### Create a Scala source code file + +Next, create a Scala program that you can use to demonstrate ScalaTest. +First, create a directory under _src/main/scala_ named _math_: + +```bash +$ mkdir src/main/scala/math + ---- +``` + +Then, inside that directory, create a file named _MathUtils.scala_ with these contents: + +```scala +package math + +object MathUtils: + def double(i: Int) = i * 2 +``` + +That method provides a simple way to demonstrate ScalaTest. + + +{% comment %} +Because this project doesn’t have a `main` method, we don’t try to run it with `sbt run`; we just compile it with `sbt compile`: + +```` +$ sbt compile + +[info] welcome to sbt +[info] loading settings for project ... +[info] loading project definition ... +[info] loading settings for project ... +[info] Executing in batch mode. For better performance use sbt's shell +[success] Total time: 1 s +```` + +With that compiled, let’s create a ScalaTest file to test the `double` method. +{% endcomment %} + + +### Your first ScalaTest tests + +ScalaTest is very flexible, and offers several different ways to write tests. +A simple way to get started is to write tests using the ScalaTest `AnyFunSuite`. +To get started, create a directory named _math_ under the _src/test/scala_ directory: + +```bash +$ mkdir src/test/scala/math + ---- +``` + +Next, create a file named _MathUtilsTests.scala_ in that directory with the following contents: + +```scala +package math + +import org.scalatest.funsuite.AnyFunSuite + +class MathUtilsTests extends AnyFunSuite: + + // test 1 + test("'double' should handle 0") { + val result = MathUtils.double(0) + assert(result == 0) + } + + // test 2 + test("'double' should handle 1") { + val result = MathUtils.double(1) + assert(result == 2) + } + + test("test with Int.MaxValue") (pending) + +end MathUtilsTests +``` + +This code demonstrates the ScalaTest `AnyFunSuite` approach. +A few important points: + +- Your test class should extend `AnyFunSuite` +- You create tests as shown, by giving each `test` a unique name +- At the end of each test you should call `assert` to test that a condition has been satisfied +- When you know you want to write a test, but you don’t want to write it right now, create the test as “pending,” with the syntax shown + +Using ScalaTest like this is similar to JUnit, so if you’re coming to Scala from Java, hopefully this looks similar. + +Now you can run these tests with the `sbt test` command. +Skipping the first few lines of output, the result looks like this: + +```` +sbt:HelloScalaTest> test + +[info] Compiling 1 Scala source ... +[info] MathUtilsTests: +[info] - 'double' should handle 0 +[info] - 'double' should handle 1 +[info] - test with Int.MaxValue (pending) +[info] Total number of tests run: 2 +[info] Suites: completed 1, aborted 0 +[info] Tests: succeeded 2, failed 0, canceled 0, ignored 0, pending 1 +[info] All tests passed. +[success] Total time: 1 s +```` + +If everything works well, you’ll see output that looks like that. +Welcome to the world of testing Scala applications with sbt and ScalaTest. + + +### Support for many types of tests + +This example demonstrates a style of testing that’s similar to xUnit _Test-Driven Development_ (TDD) style testing, with a few benefits of the _Behavior-Driven Development_ (BDD) style. + +As mentioned, ScalaTest is flexible and you can also write tests using other styles, such as a style similar to Ruby’s RSpec. +You can also use mock objects, property-based testing, and use ScalaTest to test Scala.js code. + +See the User Guide on the [ScalaTest website](https://www.scalatest.org) for more details on the different testing styles that are available. + + + +## Where to go from here + +For more information about sbt and ScalaTest, see the following resources: + +- [The sbt documentation](https://www.scala-sbt.org/1.x/docs/) +- [The ScalaTest website](https://www.scalatest.org/) + + + +[getting_started]: {{ site.baseurl }}/scala3/getting-started.html diff --git a/_overviews/scala3-book/tools-worksheets.md b/_overviews/scala3-book/tools-worksheets.md new file mode 100644 index 0000000000..3231d4e654 --- /dev/null +++ b/_overviews/scala3-book/tools-worksheets.md @@ -0,0 +1,56 @@ +--- +title: Worksheets +type: section +description: This section looks at worksheets, an alternative to Scala projects. +num: 71 +previous-page: tools-sbt +next-page: interacting-with-java +--- + +A worksheet is a Scala file that is evaluated on save, and the result of each expression is shown +in a column to the right of your program. Worksheets are like a [REPL session] on steroids, and +enjoy 1st class editor support: completion, hyperlinking, interactive errors-as-you-type, etc. +Worksheets use the extension `.worksheet.sc`. + +In the following, we show how to use worksheets in IntelliJ, and in VS Code (with the Metals extension). + +1. Open a Scala project, or create one. + - To create a project in IntelliJ, select “File” -> “New” -> “Project…”, select “Scala” + in the left column, and click “Next” to set the project name and location. + - To create a project in VS Code, run the command “Metals: New Scala project”, select the + seed `scala/scala3.g8`, set the project location, open it in a new VS Code window, and + import its build. +1. Create a file named `hello.worksheet.sc` in the directory `src/main/scala/`. + - In IntelliJ, right-click on the directory `src/main/scala/`, and select “New”, and + then “File”. + - In VS Code, right-click on the directory `src/main/scala/`, and select “New File”. +1. Paste the following content in the editor: + ~~~ + println("Hello, world!") + + val x = 1 + x + x + ~~~ +1. Evaluate the worksheet. + - In IntelliJ, click on the green arrow at the top of the editor to evaluate the worksheet. + - In VS Code, save the file. + + You should see the result of the evaluation of every line on the right panel (IntelliJ), or + as comments (VS Code). + +![]({{ site.baseurl }}/resources/images/scala3-book/intellij-worksheet.png) + +A worksheet evaluated in IntelliJ. + +![]({{ site.baseurl }}/resources/images/scala3-book/metals-worksheet.png) + +A worksheet evaluated in VS Code (with the Metals extension). + +Note that the worksheet will use the Scala version defined by your project (set by the key `scalaVersion`, +in your file `build.sbt`, typically). + +Also note that worksheets don’t have a [program entry point]. Instead, top-level statements and expressions +are evaluated from top to bottom. + +[REPL session]: {% link _overviews/scala3-book/taste-repl.md %} +[program entry point]: {% link _overviews/scala3-book/methods-main-methods.md %} diff --git a/resources/images/scala3-book/intellij-worksheet.png b/resources/images/scala3-book/intellij-worksheet.png new file mode 100644 index 0000000000000000000000000000000000000000..e33fd3566e8c43b3e32aeb06a951f69f57bdd03b GIT binary patch literal 12899 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 literal 0 HcmV?d00001 From 8c1ff35b174b2446b9be5e9739c1d79164b07779 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Mon, 5 Jul 2021 16:27:14 +0200 Subject: [PATCH 1549/3075] Create docs.scala-lang.org/scala3/guides/reference and move language-versions here Content was taken from commit 270bd8b0f5af338be73790082d774516a83a73b5 --- _config.yml | 11 +++++- .../scala3-reference/language-versions.md | 36 +++++++++++++++++++ _overviews/scala3-reference/overview.md | 7 ++++ scala3/guides.md | 4 +++ 4 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 _overviews/scala3-reference/language-versions.md create mode 100644 _overviews/scala3-reference/overview.md diff --git a/_config.yml b/_config.yml index ea13ad3eae..395bed4a34 100644 --- a/_config.yml +++ b/_config.yml @@ -123,6 +123,15 @@ defaults: overview-name: "Macros in Scala 3" layout: multipage-overview permalink: "/scala3/guides/macros/:title.html" + - + scope: + path: "_overviews/scala3-reference" + values: + scala3: true + partof: scala3-reference + overview-name: "Scala 3 Language Reference" + layout: multipage-overview + permalink: "/scala3/guides/reference/:title.html" - scope: path: "scala3" @@ -133,7 +142,7 @@ defaults: highlighter: rouge permalink: /:categories/:title.html:output_ext baseurl: -scala3ref: "https://dotty.epfl.ch/docs/reference" +scala3ref: "/scala3/guides/reference" exclude: ["vendor"] plugins: - jekyll-redirect-from diff --git a/_overviews/scala3-reference/language-versions.md b/_overviews/scala3-reference/language-versions.md new file mode 100644 index 0000000000..01a8ab1c32 --- /dev/null +++ b/_overviews/scala3-reference/language-versions.md @@ -0,0 +1,36 @@ +--- +title: Language Versions +type: chapter +description: This page lists the different flavours of language supported by the Scala 3 compiler. +num: 2 +previous-page: overview +--- + +The default Scala language version currently supported by the Dotty compiler is `3.0`. There are also other language versions that can be specified instead: + +- `3.0-migration`: Same as `3.0` but with a Scala 2 compatibility mode that helps moving Scala 2.13 sources over to Scala 3. In particular, it + + - flags some Scala 2 constructs that are disallowed in Scala 3 as migration warnings instead of hard errors, + - changes some rules to be more lenient and backwards compatible with Scala 2.13 + - gives some additional warnings where the semantics has changed between Scala 2.13 and 3.0 + - in conjunction with `-rewrite`, offer code rewrites from Scala 2.13 to 3.0. + +- `future`: A preview of changes introduced in the next versions after 3.0. In the doc pages here we refer to the language version with these changes as `3.1`, but it might be that some of these changes will be rolled out in later `3.x` versions. + +Some Scala-2 specific idioms will be dropped in this version. The feature set supported by this version will be refined over time as we approach its release. + +- `future-migration`: Same as `future` but with additional helpers to migrate from `3.0`. Similarly to the helpers available under `3.0-migration`, these include migration warnings and optional rewrites. + +There are two ways to specify a language version. + +- With a `-source` command line setting, e.g. `-source 3.0-migration`. +- With a `scala.language` import at the top of a source file, e.g: + +```scala +package p +import scala.language.`future-migration` + +class C { ... } +``` + +Language imports supersede command-line settings in the source files where they are specified. Only one language import specifying a source version is allowed in a source file, and it must come before any definitions in that file. diff --git a/_overviews/scala3-reference/overview.md b/_overviews/scala3-reference/overview.md new file mode 100644 index 0000000000..aa34ec188f --- /dev/null +++ b/_overviews/scala3-reference/overview.md @@ -0,0 +1,7 @@ +--- +title: Overview +type: chapter +description: This page begins the reference documentation. +num: 1 +next-page: language-versions +--- diff --git a/scala3/guides.md b/scala3/guides.md index 45587d280f..e6ddb733db 100644 --- a/scala3/guides.md +++ b/scala3/guides.md @@ -18,6 +18,10 @@ guides: icon: birthday-cake url: "/scala3/guides/tasty-overview.html" description: "An overview over the TASTy format aimed at end-users of the Scala language." + - title: Scala 3 Language Reference + icon: book + url: "/scala3/guides/reference/overview.html" + description: "The reference for Scala 3" --- \ No newline at end of file + diff --git a/_layouts/frontpage.html b/_layouts/frontpage.html index 743e27bd83..29fa5825fe 100644 --- a/_layouts/frontpage.html +++ b/_layouts/frontpage.html @@ -299,24 +299,24 @@

{{forum.title}}

{% endfor %} -
-

Real-time (topic-specialized) chat

- {% assign modLimit = site.data.chats-forums.gitterChannels.size | modulo: 2 %} +
+

Real-time chat

+ {% assign modLimit = site.data.chats-forums.discordServers.size | modulo: 2 %} {% capture channelLimit %} {% if modLimit != 0 %} - {{site.data.chats-forums.gitterChannels.size | minus: 1}} + {{site.data.chats-forums.discordServers.size | minus: 1}} {% else %} - {{site.data.chats-forums.gitterChannels.size}} + {{site.data.chats-forums.discordServers.size}} {% endif %} {% endcapture %} - {% for channel in site.data.chats-forums.gitterChannels limit: channelLimit %} + {% for server in site.data.chats-forums.discordServers limit: channelLimit %} {% if forloop.first %}
From 2dd2d506445008554d88614618b9faf28b16a355 Mon Sep 17 00:00:00 2001 From: Horimoto Yasuhiro Date: Wed, 9 Feb 2022 23:19:53 +0900 Subject: [PATCH 1778/3075] Add a missing translation in getting-started.md (Japanese) --- _includes/_ja/getting-started.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/_ja/getting-started.md b/_includes/_ja/getting-started.md index 97ebcbd692..f70eba4848 100644 --- a/_includes/_ja/getting-started.md +++ b/_includes/_ja/getting-started.md @@ -150,7 +150,7 @@ Scala について日本語で質問したい場合、Twitterでつぶやくと
From 1dd5138701fd92d82ebe284f49e566c39e1e68db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 10 Feb 2022 16:57:43 +0100 Subject: [PATCH 1779/3075] Update the Getting Started page(s) for the latest `cs` behavior. The default installation of coursier now installs Scala 3 by default under `scala` and `scalac`. However, it also allows to override that with `cs launch scala:2.13.8` or `cs install scala:2.13.8`, as Scala 2 and Scala 3 have been unified. --- _includes/getting-started.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/_includes/getting-started.md b/_includes/getting-started.md index dcbf448b0f..628f2a41c5 100644 --- a/_includes/getting-started.md +++ b/_includes/getting-started.md @@ -34,20 +34,24 @@ Along with managing JVMs, `cs setup` also installs useful command-line tools: - The [sbt](https://www.scala-sbt.org/) build tool - [Ammonite](https://ammonite.io/), an enhanced REPL - [scalafmt](https://scalameta.org/scalafmt/), the Scala code formatter -- `scalac` (the Scala 2 compiler) -- `scala` (the Scala 2 REPL and script runner). +- `scalac` (the Scala compiler) +- `scala` (the Scala REPL and script runner). For more information about `cs`, read [coursier-cli documentation](https://get-coursier.io/docs/cli-overview). -> Currently, `cs setup` installs the Scala 2 compiler and runner (the `scalac` and -> `scala` commands, respectively). This is usually not an issue because most projects -> use a build tool that works with both Scala 2 and Scala 3. -> Nevertheless, you can install the Scala 3 compiler and runner as command-line tools -> by running the following additional commands: +> `cs setup` installs the Scala 3 compiler and runner by default (the `scalac` and +> `scala` commands, respectively). Whether you intend to use Scala 2 or 3, +> this is usually not an issue because most projects use a build tool that will +> use the correct version of Scala irrespective of the one installed "globally". +> Nevertheless, you can always launch a specific version of Scala using > ``` -> $ cs install scala3-compiler -> $ cs install scala3 +> $ cs launch scala:{{ site.scala-version }} +> $ cs launch scalac:{{ site.scala-version }} +> ``` +> If you prefer Scala 2 to be run by default, you can force that version to be installed with: +> ``` +> $ cs install scala:{{ site.scala-version }} scalac:{{ site.scala-version }} > ``` ### ...or manually @@ -164,7 +168,7 @@ There are a multitude of mailing lists and real-time chat rooms in case you want + --> From 30f11ac17dbe37d7edc46bd64450dd030207b07d Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Thu, 10 Feb 2022 20:02:07 -0800 Subject: [PATCH 1780/3075] Mention library version quirk --- _overviews/FAQ/index.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/_overviews/FAQ/index.md b/_overviews/FAQ/index.md index d20c5d7a4b..fe4b457451 100644 --- a/_overviews/FAQ/index.md +++ b/_overviews/FAQ/index.md @@ -105,9 +105,22 @@ get poor results, try surrounding the symbol with double quotes. sbt 1.x always uses Scala 2.12 to compile build definitions. Your sbt 1.x build definition is always a Scala 2.12 program. -Regardless, in your `build.sbt` you can set `scalaVersion` to anything -you want and your actual program code will be compiled with that -version. +Regardless, in your `build.sbt`, you can set `scalaVersion` to whichever +available distribution you want and your program code will be compiled with that version. + +### I want Scala 3.1.1 (etc); why does std lib say it's using Scala 2.13? + +Scala 3 currently uses the Scala 2.13 library by leveraging its seamless +interoperability. Note that it does not necessarily ingest the latest +version of the Scala 2.13 library. + +``` +Welcome to Scala 3.1.1 (17.0.2, Java OpenJDK 64-Bit Server VM). +Type in expressions for evaluation. Or try :help. + +scala> util.Properties.versionString +val res0: String = version 2.13.6 +``` ### Why is my (abstract or overridden) `val` null? From dcc51592443ca85e535c71068137865daf1ef17e Mon Sep 17 00:00:00 2001 From: czasoprzestrzenny <46657059+czasoprzestrzenny@users.noreply.github.com> Date: Fri, 11 Feb 2022 15:41:48 +0100 Subject: [PATCH 1781/3075] Update generic-classes.md changed a stack pop to stack.pop() --- _tour/generic-classes.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_tour/generic-classes.md b/_tour/generic-classes.md index 0b479d30df..d883e88115 100644 --- a/_tour/generic-classes.md +++ b/_tour/generic-classes.md @@ -38,8 +38,8 @@ To use a generic class, put the type in the square brackets in place of `A`. val stack = new Stack[Int] stack.push(1) stack.push(2) -println(stack.pop) // prints 2 -println(stack.pop) // prints 1 +println(stack.pop()) // prints 2 +println(stack.pop()) // prints 1 ``` The instance `stack` can only take Ints. However, if the type argument had subtypes, those could be passed in: ``` From 15ba133475ab1f48392e0b82f1356d93899f2178 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Tue, 15 Feb 2022 10:37:40 +0100 Subject: [PATCH 1782/3075] update install instructions for coursier Use the same instructions as listed on the official Coursier website, as git.io short url service is no longer maintained. --- _includes/_ja/getting-started.md | 8 ++++---- _includes/getting-started.md | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/_includes/_ja/getting-started.md b/_includes/_ja/getting-started.md index 0fe5652204..40bcf9ff29 100644 --- a/_includes/_ja/getting-started.md +++ b/_includes/_ja/getting-started.md @@ -14,7 +14,7 @@ Scala をインストールすると、コンパイラやビルドツールな ### Scala インストーラーを使う(推奨) -Scala のインストーラーは[Coursier](https://get-coursier.io/docs/cli-overview)というツールで、コマンドは`cs`です。このツールを使うと、JVM と標準 Scala ツールがシステムにインストールされます。 +Scala のインストーラーは[Coursier](https://get-coursier.io/docs/cli-overview)というツールで、コマンドは`cs`です。このツールを使うと、JVM と標準 Scala ツールがシステムにインストールされます。 以下の手順でお使いのシステムにインストールしてください。
@@ -146,7 +146,7 @@ Scala について日本語で質問したい場合、Twitterでつぶやくと -- This is handled in `resources/js/functions.js`. -->

または、Homebrewを使用しない場合は

- $ curl -fLo cs https://git.io/coursier-cli-macos && chmod +x cs && (xattr -d com.apple.quarantine cs || true) && ./cs setup
+ $ curl -fL https://github.com/coursier/launchers/raw/master/cs-x86_64-apple-darwin.gz | gzip -d > cs && chmod +x cs && (xattr -d com.apple.quarantine cs || true) && ./cs setup
diff --git a/_includes/getting-started.md b/_includes/getting-started.md index 628f2a41c5..83c1de45fe 100644 --- a/_includes/getting-started.md +++ b/_includes/getting-started.md @@ -170,7 +170,7 @@ There are a multitude of mailing lists and real-time chat rooms in case you want -- This is handled in `resources/js/functions.js`. -->

Alternatively, if you don't use Homebrew

- $ curl -fLo cs https://git.io/coursier-cli-macos && chmod +x cs && (xattr -d com.apple.quarantine cs || true) && ./cs setup
+ $ curl -fL https://github.com/coursier/launchers/raw/master/cs-x86_64-apple-darwin.gz | gzip -d > cs && chmod +x cs && (xattr -d com.apple.quarantine cs || true) && ./cs setup
From b3e7f156841a4b3b7ec3f36d739f01d3c65874b1 Mon Sep 17 00:00:00 2001 From: Bersier Date: Wed, 16 Feb 2022 16:06:11 -0500 Subject: [PATCH 1783/3075] Update staging.md Added a link for "PCP". --- _scala3-reference/metaprogramming/staging.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_scala3-reference/metaprogramming/staging.md b/_scala3-reference/metaprogramming/staging.md index 0e90966c85..bb35f51055 100644 --- a/_scala3-reference/metaprogramming/staging.md +++ b/_scala3-reference/metaprogramming/staging.md @@ -62,7 +62,7 @@ impose the following restrictions on the use of splices. The framework as discussed so far allows code to be staged, i.e. be prepared to be executed at a later stage. To run that code, there is another method in class `Expr` called `run`. Note that `$` and `run` both map from `Expr[T]` -to `T` but only `$` is subject to the PCP, whereas `run` is just a normal method. +to `T` but only `$` is subject to the [PCP](./macros.html#the-phase-consistency-principle), whereas `run` is just a normal method. `scala.quoted.staging.run` provides a `Quotes` that can be used to show the expression in its scope. On the other hand `scala.quoted.staging.withQuotes` provides a `Quotes` without evaluating the expression. From 99b84bc5a89a1e76535abbea3199d1bb8ee31020 Mon Sep 17 00:00:00 2001 From: Ye Shu Date: Sun, 20 Feb 2022 18:58:55 -0500 Subject: [PATCH 1784/3075] Fix deprecated warning in scala for java programer ``` warning: method + in class Int is deprecated (since 2.13.0): Adding a number and a String is deprecated. Use the string interpolation `s"$num$str"` override def toString(): String = year + "-" + month + "-" + day ``` --- _it/tutorials/scala-for-java-programmers.md | 2 +- _ja/tutorials/scala-for-java-programmers.md | 2 +- _ko/tutorials/scala-for-java-programmers.md | 2 +- _overviews/tutorials/scala-for-java-programmers.md | 2 +- _zh-cn/tutorials/scala-for-java-programmers.md | 2 +- _zh-tw/tutorials/scala-for-java-programmers.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/_it/tutorials/scala-for-java-programmers.md b/_it/tutorials/scala-for-java-programmers.md index 5cf8cb4b1c..7a60a2d6c6 100644 --- a/_it/tutorials/scala-for-java-programmers.md +++ b/_it/tutorials/scala-for-java-programmers.md @@ -578,7 +578,7 @@ definendo la classe `Date` come segue: def year = y def month = m def day = d - override def toString(): String = year + "-" + month + "-" + day + override def toString(): String = s"$year-$month-$day" La parte importante qui è la dichiarazione `extends Ord` che segue il nome della classe e dei parametri. Dichiara che la classe `Date` eredita il diff --git a/_ja/tutorials/scala-for-java-programmers.md b/_ja/tutorials/scala-for-java-programmers.md index 8d6fb7aef3..b49113ff72 100644 --- a/_ja/tutorials/scala-for-java-programmers.md +++ b/_ja/tutorials/scala-for-java-programmers.md @@ -461,7 +461,7 @@ Java の `Object` 型のより一般的なものとしてとらえられます def year = y def month = m def day = d - override def toString(): String = year + "-" + month + "-" + day + override def toString(): String = s"$year-$month-$day" ここで重要なのは、クラス名とパラメータのあとに続く `extends Ord` という宣言です。 `Date` クラスが `Ord` トレイトを継承していることを宣言しています。 diff --git a/_ko/tutorials/scala-for-java-programmers.md b/_ko/tutorials/scala-for-java-programmers.md index 4f26dee244..b3f3d1b6d3 100644 --- a/_ko/tutorials/scala-for-java-programmers.md +++ b/_ko/tutorials/scala-for-java-programmers.md @@ -547,7 +547,7 @@ Java 프로그래머들이 트레잇을 이해하는 가장 쉬운 길은 코드 def year = y def month = m def day = d - override def toString(): String = year + "-" + month + "-" + day + override def toString(): String = s"$year-$month-$day" 여기서 중요한 부분은 클래스 이름과 파라미터 뒤에 따라오는 `extends Ord` 선언이다. 이 선언은 `Date` 클래스가 `Ord` diff --git a/_overviews/tutorials/scala-for-java-programmers.md b/_overviews/tutorials/scala-for-java-programmers.md index 52c988066e..ebac87fce3 100644 --- a/_overviews/tutorials/scala-for-java-programmers.md +++ b/_overviews/tutorials/scala-for-java-programmers.md @@ -595,7 +595,7 @@ represent as integers. We therefore start the definition of the def year = y def month = m def day = d - override def toString(): String = year + "-" + month + "-" + day + override def toString(): String = s"$year-$month-$day" The important part here is the `extends Ord` declaration which follows the class name and parameters. It declares that the diff --git a/_zh-cn/tutorials/scala-for-java-programmers.md b/_zh-cn/tutorials/scala-for-java-programmers.md index 9ee8838b4d..00559b596d 100644 --- a/_zh-cn/tutorials/scala-for-java-programmers.md +++ b/_zh-cn/tutorials/scala-for-java-programmers.md @@ -308,7 +308,7 @@ Java 中我们会将这个树用一个抽象父类表示,然后每种节点跟 def year = y def month = m def day = d - override def toString(): String = year + "-" + month + "-" + day + override def toString(): String = s"$year-$month-$day" 这边要注意的是声明在类名称跟参数之后的 `extends Ord`。这个语法声明了 `Date` 继承 `Ord` 特质。 diff --git a/_zh-tw/tutorials/scala-for-java-programmers.md b/_zh-tw/tutorials/scala-for-java-programmers.md index 290ee22ac3..d9b4bcd4d0 100755 --- a/_zh-tw/tutorials/scala-for-java-programmers.md +++ b/_zh-tw/tutorials/scala-for-java-programmers.md @@ -308,7 +308,7 @@ Java 中我們會將這個樹用一個抽象母類別表示,然後每種節點 def year = y def month = m def day = d - override def toString(): String = year + "-" + month + "-" + day + override def toString(): String = s"$year-$month-$day" 這邊要注意的是宣告在類別名稱跟參數之後的 `extends Ord`。這個語法宣告了 `Date` 繼承 `Ord` 特質。 From cf096aebaaceb121695d1aea973c5216c97d8437 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Wed, 23 Feb 2022 20:24:54 -0800 Subject: [PATCH 1785/3075] Add lightbend blog post --- _overviews/compiler-options/optimizer.md | 221 +++++++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 _overviews/compiler-options/optimizer.md diff --git a/_overviews/compiler-options/optimizer.md b/_overviews/compiler-options/optimizer.md new file mode 100644 index 0000000000..a5cf6fbb29 --- /dev/null +++ b/_overviews/compiler-options/optimizer.md @@ -0,0 +1,221 @@ +# The Scala 2.12 / 2.13 Inliner and Optimizer + +_by [Lukas Rytz](https://github.com/lrytz), November 7, 2018_ + +tl;dr: + +- Don't enable the optimizer during development: it breaks incremental compilation, and it makes the compiler slower. Only enable it for testing, on CI, and to build releases. +- Enable method-local optimizations with `-opt:l:method`. This option is safe for binary compatibility, but typically doesn't improve performance on its own. +- Enable inlining in addition to method-local optimizations with `-opt:l:inline` and `-opt-inline-from:[PATTERN]` + - Don't inline from your dependencies when publishing a library, it breaks binary compatibility. Use `-opt-inline-from:my.package.**` to only inline from packages within your library. + - When compiling an application with global inlining (`-opt-inline-from:**`), ensure that the run-time classpath is exactly the same as the compile-time classpath. +- The `@inline` annotation only has an effect if the inliner is enabled. It tells the inliner to always try to inline the annotated method or callsite. +- Without the `@inline` annotation, the inliner generally inlines higher-order methods and forwarder methods. The main goal is to eliminate megamorphic callsites due to functions passed as argument, and to eliminate value boxing. Other optimizations are delegated to the JVM. + +To learn more, read on. + +## Intro + +The Scala compiler has included an inliner since version 2.0. Closure elimination and dead code elimination were added in 2.1. That was the first Scala optimizer, written and maintained by [Iulian Dragos](https://github.com/dragos). He continued to improve these features over time and consolidated them under the `-optimise` flag (later Americanized to `-optimize`), which remained available through Scala 2.11. + +The optimizer was re-written for Scala 2.12 to become more reliable and powerful – and to side-step the spelling issue by calling the new flag `-opt`. This post describes how to use the optimizer in Scala 2.12 and 2.13: what it does, how it works, and what are its limitations. + +## Motivation + +Why does the Scala compiler even have a JVM bytecode optimizer? The JVM is a highly optimized runtime with a just-in-time (JIT) compiler with 19 years of tuning. It's because there are certain well-known code patterns that the JVM fails to optimize properly. These patterns are common in functional languages such as Scala. (Increasingly, Java code with lambdas is catching up and showing the same performance issues at run-time.) + +The two most important such patterns are "megamorphic dispatch" (also called "the inlining problem") and value boxing. If you'd like to learn more about these problems in the context of Scala, you could watch the part of [my Scala Days 2015 talk (starting at 26:13)](https://youtu.be/Ic4vQJcYwsU?t=1573). + +The goal of the Scala optimizer is to produce bytecode that the JVM can execute fast. It is also a goal to avoid performing any optimizations that the JVM can already do well. + +This means that the Scala optimizer may become obsolete in the future, if the JIT compiler is improved to handle these patterns better. In fact, with the arrival of GraalVM, that future might be nearer than you think! We take a closer look at Graal in a follow-up post. But for now, we dive into some details about the Scala optimizer. + +## Constraints and assumptions + +The Scala optimizer has to make its improvements within fairly narrow constraints: + +- The optimizer only changes method bodies, but never signatures of classes or methods. The generated bytecode has the same (binary) interface, whether or not the optimizer is enabled. +- We don't assume the whole program (all user code plus all of its dependencies, that together make up an application) is known when running the optimizer. There may be classes on the run-time classpath that we don't see at compile-time: we may be compiling a library, or only a component of an application. This means that: + - Every non-final method can potentially be overridden, even if at compile-time there are no classes that define such an override + - Consequently, we can only inline methods that can be resolved at compile-time: final methods, methods in `object`s, and methods where the receiver's type is precisely known (for example, in `(new A).f`, the receiver is known to be exactly `A`, not a subtype of `A`). +- The optimizer does not break applications that use reflection. This follows from the two points above: changes to classes could be observed by reflection, and additional classes could be loaded and instantiated dynamically. + +However, even when staying within these constraints, some changes performed by the optimizer can be observed at run-time: + +- Inlined methods disappear from call stacks. + + - This can lead to unexpected behaviors when using a debugger. + - Related: line numbers (stored in bytecode) are discarded when a method is inlined into a different classfile, which also impacts debugging experience. (This [could be improved](https://github.com/scala/scala-dev/issues/3).) + +- Inlining a method can delay class loading of the class where the method is defined. + +- The optimizer assumes that modules (singletons like `object O`) are never `null`. + - This assumption can be false if the module is loaded in its superclass. The following example throws a `NullPointerException` when compiled normally, but prints `0` when compiled with the optimizer enabled: + + ```scala + class A { + println(Test.f) + } + object Test extends A { + @inline def f = 0 + def main(args: Array[String]): Unit = () + } + ``` + + - This assumption can be disabled with `-opt:-assume-modules-non-null`, which results in additional null checks in optimized code. + +- The optimizer removes unnecessary loads of certain built-in modules, for example `scala.Predef` and `scala.runtime.ScalaRunTime`. This means that initialization (construction) of these modules can be skipped or delayed. + + - For example, in `def f = 1 -> ""`, the method `Predef.->` is inlined and the access to `Predef` is eliminated. The resulting code is `def f = new Tuple2(1, "")`. + - This assumption can be disabled with `-opt:-allow-skip-core-module-init` + +- The optimizer eliminates unused `C.getClass` calls, which may delay class loading. This can be disabled with `-opt:-allow-skip-class-loading`. + +## Binary compatibility + +Scala minor releases are binary compatible with each other, for example 2.12.6 and 2.12.7. The same is true for many libraries in the Scala ecosystem. These binary compatibility promises are the main reason for the Scala optimizer not to be enabled everywhere. + +The reason is that inlining a method from one class into another changes the (binary) interface that is accessed: + +```scala +class C { + private[this] var x = 0 + @inline final def inc(): Int = { x += 1; x } +} +``` + +When inlining a callsite `c.inc()`, the resulting code no longer calls `inc`, but instead accesses the field `x` directly. Since that field is private (also in bytecode), inlining `inc` is only allowed within the class `C` itself. Trying to access `x` from any other class would cause an `IllegalAccessError` at run-time. + +However, there are many cases where implementation details in Scala source code become public in bytecode: + +```scala +class C { + private def x = 0 + @inline final def m: Int = x +} +object C { + def t(c: C) = c.x +} +``` + +Scala allows accessing the private method `x` in the companion object `C`. In bytecode, however, the classfile for the companion `C$` is not allowed to access a private method of `C`. For that reason, the Scala compiler "mangles" the name of `x` to `C$$x` and makes the method public. + +This means that `m` can be inlined into classes other than `C`, since the resulting code invokes `C.C$$x` instead of `C.m`. Unfortunately this breaks Scala's binary compatibility promise: the fact that the public method `m` calls a private method `x` is considered to be an implementation detail that can change in a minor release of the library defining `C`. + +Even more trivially, assume that method `m` was buggy and is changed to `def m = if (fullMoon) 1 else x` in a minor release. Normally, it would be enough for a user to put the new version on the classpath. However, if the old version of `c.m` was inlined at compile-time, having the new version of C on the run-time classpath would not fix the bug. + +In order to safely use the Scala optimizer, users need to make sure that the compile-time and run-time classpaths are identical. This has a far-reaching consequence for library developers: **libraries that are published to be consumed by other projects should not inline code from the classpath**. The inliner can be configured to inline code from the library itself using `-opt-inline-from:my.package.**`. + +The reason for this restriction is that dependency management tools like sbt will often pick newer versions of transitive dependencies. For example, if library `A` depends on `core-1.1.1`, `B` depends on `core-1.1.2` and the application depends on both `A` and `B`, the build tool will put `core-1.1.2` on the classpath. If code from `core-1.1.1` was inlined into `A` at compile-time, it might break at run-time due to a binary incompatibility. + +## Using and interacting with the optimizer + +The compiler flag for enabling the optimizer is `-opt`. Running `scalac -opt:help` shows how to use the flag. + +By default (without any compiler flags, or with `-opt:l:default`), the Scala compiler eliminates unreachable code, but does not run any other optimizations. + +`-opt:l:method` enables all method-local optimizations, for example: + +- Elimination of code that loads unused values +- Rewriting of null and `isInstanceOf` checks whose result is known at compile-time +- Elimination of value boxes like `java.lang.Integer` or `scala.runtime.DoubleRef` that are created within a method and don't escape it + +Individual optimizations can be disabled. For example, `-opt:l:method,-nullness-tracking` disables nullness optimizations. + +Method-local optimizations alone typically don't have any positive effect on performance, because source code usually doesn't have unnecessary boxing or null checks. However, local optimizations can often be applied after inlining, so it's really the combination of inlining and local optimizations that can improve program performance. + +`-opt:l:inline` enables inlining in addition to method-local optimizations. However, to avoid unexpected binary compatibility issues, we also need to tell the compiler which code it is allowed to inline. This is done with the `-opt-inline-from` compiler flag. Examples: + +- `-opt-inline-from:my.library.**` enables inlining from any class defined in package `my.library`, or in any of its sub-packages. Inlining within a library is safe for binary compatibility, so the resulting binary can be published. It will still work correctly even if one of its dependencies is updated to a newer minor version in the run-time classpath. +- `-opt-inline-from:` enables inlining from the set of source files being compiled in the current compiler invocation. This option can also be used for compiling libraries. If the source files of a library are split up across multiple sbt projects, inlining is only done within each project. Note that in an incremental compilation, inlining would only happen within the sources being re-compiled – but in any case, it is recommended to only enable the optimizer in CI and release builds (and to run `clean` before building). +- `-opt-inline-from:**` allows inlining from every class, including the JDK. This option enables full optimization when compiling an application. To avoid binary incompatibilities, it is mandatory to ensure that the run-time classpath is identical to the compile-time classpath, including the Java standard library. + +Running `scalac -opt-inline-from:help` explains how to use the compiler flag. + +### Inliner heuristics and `@inline` + +When the inliner is enabled, it automatically selects callsites for inlining according to a heuristic. + +As mentioned in the introduction, the main goal of the Scala optimizer is to eliminate megamorphic dispatch and value boxing. In order to keep this post from growing too long, a followup post will include the analysis of concrete examples that motivate which callsites are selected by the inliner heuristic. + +Nevertheless, it is useful to have an intuition of how the heuristic works, so here is an overview: + +- Methods or callsites annotated [`@noinline`](https://www.scala-lang.org/api/current/scala/noinline.html) are not inlined. +- The inliner doesn't inline *into* forwarder methods. +- Methods or callsites annotated [`@inline`](https://www.scala-lang.org/api/current/scala/inline.html) are inlined. +- Higher-order methods with a function literal as argument are inlined. +- Higher-order methods where a parameter function of the callsite method is forwarded to the callee are inlined. +- Methods with an `IntRef` / `DoubleRef` / ... parameter are inlined. When nested methods update variables of the outer method, those variables are boxed into `XRef` objects. These boxes can often be eliminated after inlining the nested method. +- Forwarders, factory methods and trivial methods are inlined. Examples include simple closure bodies like `_ + 1` and synthetic methods (potentially with boxing / unboxing adaptations) such as bridges. + +To prevent methods from exceeding the JVM's method size limit, the inliner has size limits. Inlining into a method stops when the number of instructions exceeds a certain threshold. + +As you can see in the list above, the `@inline` and `@noinline` annotations are the only way for programmers to influence inlining decisions. In general, our recommendation is to avoid using these annotations. If you observe issues with the inliner heuristic that can be fixed by annotating methods, we are very keen to hear about them, for example in the form of a [bug report](https://github.com/scala/bug/issues). + +A related anecdote: in the Scala compiler and standard library (which are built with the optimizer enabled), there are roughly 330 `@inline`-annotated methods. Removing all of these annotations and re-building the project has no effect on the compiler's performance. So the annotations are well-intended and benign, but in reality unnecessary. + +For expert users, `@inline` annotations can be used to hand-tune performance critical code without reducing abstraction. If you have a project that falls into this category, please [let us know](https://contributors.scala-lang.org), we're interested to learn more! + +Finally, note that the `@inline` annotation only has an effect when the inliner is enabled, which is not the case by default. The reason is to avoid introducing accidental binary incompatibilities, as [explained above](#binary-compatibility). + +### Inliner warnings + +The inliner can issue warnings when callsites cannot be inlined. By default, these warnings are not issued individually, but only as a summary at the end of compilation (similar to deprecation warnings). + +``` +$> scalac Test.scala -opt:l:inline '-opt-inline-from:**' +warning: there was one inliner warning; re-run enabling -opt-warnings for details, or try -help +one warning found + +$> scalac Test.scala -opt:l:inline '-opt-inline-from:**' -opt-warnings +Test.scala:3: warning: C::f()I is annotated @inline but could not be inlined: +The method is not final and may be overridden. + def t = f + ^ +one warning found +``` + +By default, the inliner issues warnings for invocations of methods annotated `@inline` that cannot be inlined. Here is the source code that was compiled in the commands above: + +```scala +class C { + @inline def f = 1 + def t = f // cannot inline: C.f is not final +} +object T extends C { + override def t = f // can inline: T.f is final +} +``` + +The `-opt-warnings` flag has more configurations. With `-opt-warnings:_`, a warning is issued for every callsite that is selected by the heuristic but cannot be inlined. See also `-opt-warnings:help`. + +### Inliner log + +If you're curious (or maybe even skeptical) about what the inliner is doing to your code, you can use the `-Yopt-log-inline` flag to produce a trace of the inliner's work: + +```scala +package my.project +class C { + def f(a: Array[Int]) = a.map(_ + 1) +} +``` + +``` +$> scalac Test.scala -opt:l:inline '-opt-inline-from:**' -Yopt-log-inline my/project/C.f +Inlining into my/project/C.f + inlined scala/Predef$.intArrayOps (the callee is annotated `@inline`). Before: 15 ins, after: 30 ins. + inlined scala/collection/ArrayOps$.map$extension (the callee is a higher-order method, the argument for parameter (evidence$6: Function1) is a function literal). Before: 30 ins, after: 94 ins. + inlined scala/runtime/ScalaRunTime$.array_length (the callee is annotated `@inline`). Before: 94 ins, after: 110 ins. + [...] + rewrote invocations of closure allocated in my/project/C.f with body $anonfun$f$1: INVOKEINTERFACE scala/Function1.apply (Ljava/lang/Object;)Ljava/lang/Object; (itf) + inlined my/project/C.$anonfun$f$1 (the callee is a synthetic forwarder method). Before: 654 ins, after: 666 ins. + inlined scala/runtime/BoxesRunTime.boxToInteger (the callee is a forwarder method with boxing adaptation). Before: 666 ins, after: 674 ins. +``` + +Explaining the details here is out of scope for this post. We defer this discussion to a follow-up post that will explain the internals of the Scala optimizer in more detail. + +## Summary + +The goal of this article was to explain why the Scala optimizer exists and give a rough explanation what it can and cannot do. It also showed how to configure and use the optimizer in your project. + +In the next post, we will go into detail about how the optimizer works, what transformations are applied, and how they work together. We will also measure performance improvements that the optimizer can bring. Finally, we will look at related projects, dive a little more into the history of the optimizer, and discuss ideas for the future. From 13f8c85396d73527fdeab4372455424e1ed3a615 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Wed, 23 Feb 2022 21:39:23 -0800 Subject: [PATCH 1786/3075] Update optimizer overview --- _data/overviews.yml | 5 ++ _overviews/compiler-options/optimizer.md | 68 ++++++++++++------------ 2 files changed, 40 insertions(+), 33 deletions(-) diff --git a/_data/overviews.yml b/_data/overviews.yml index cf89f286a7..ae56e9b5e9 100644 --- a/_data/overviews.yml +++ b/_data/overviews.yml @@ -259,6 +259,11 @@ icon: cog url: "compiler-options/errors.html" description: "A new engine for more user-friendly error messages, printing chains of dependent implicits and colored found/required type diffs." + - title: Optimizer + by: Lukas Rytz and Andrew Marki + icon: cog + url: "compiler-options/optimizer.html" + description: "The compiler can perform various optimizations as specified by compiler options." - category: Legacy diff --git a/_overviews/compiler-options/optimizer.md b/_overviews/compiler-options/optimizer.md index a5cf6fbb29..936967e8a0 100644 --- a/_overviews/compiler-options/optimizer.md +++ b/_overviews/compiler-options/optimizer.md @@ -1,18 +1,26 @@ -# The Scala 2.12 / 2.13 Inliner and Optimizer +--- +layout: singlepage-overview +title: Optimizer +--- + +**[Lukas Rytz](https://github.com/lrytz) (November 7, 2018)** -_by [Lukas Rytz](https://github.com/lrytz), November 7, 2018_ +**[Andrew Marki](https://github.com/som-snytt) (February 29, 2022)** -tl;dr: +# The Scala 2.12 / 2.13 Inliner and Optimizer +## In Brief + +- The Scala compiler has a compile-time optimizer that is available in versions 2.12 and 2.13, but not yet in Scala 3. - Don't enable the optimizer during development: it breaks incremental compilation, and it makes the compiler slower. Only enable it for testing, on CI, and to build releases. -- Enable method-local optimizations with `-opt:l:method`. This option is safe for binary compatibility, but typically doesn't improve performance on its own. -- Enable inlining in addition to method-local optimizations with `-opt:l:inline` and `-opt-inline-from:[PATTERN]` - - Don't inline from your dependencies when publishing a library, it breaks binary compatibility. Use `-opt-inline-from:my.package.**` to only inline from packages within your library. - - When compiling an application with global inlining (`-opt-inline-from:**`), ensure that the run-time classpath is exactly the same as the compile-time classpath. +- Enable method-local optimizations with `-opt:local`. This option is safe for binary compatibility, but typically doesn't improve performance on its own. +- Enable inlining in addition to method-local optimizations with `-opt:inline:[PATTERN]`. + - Don't inline from your dependencies when publishing a library, it breaks binary compatibility. Use `-opt:inline:my.package.**` to only inline from packages within your library. + - When compiling an application with global inlining (`-opt:inline:**`), ensure that the run-time classpath is **exactly the same** as the compile-time classpath. - The `@inline` annotation only has an effect if the inliner is enabled. It tells the inliner to always try to inline the annotated method or callsite. - Without the `@inline` annotation, the inliner generally inlines higher-order methods and forwarder methods. The main goal is to eliminate megamorphic callsites due to functions passed as argument, and to eliminate value boxing. Other optimizations are delegated to the JVM. -To learn more, read on. +Read more to learn more. ## Intro @@ -20,15 +28,17 @@ The Scala compiler has included an inliner since version 2.0. Closure eliminatio The optimizer was re-written for Scala 2.12 to become more reliable and powerful – and to side-step the spelling issue by calling the new flag `-opt`. This post describes how to use the optimizer in Scala 2.12 and 2.13: what it does, how it works, and what are its limitations. +The options were simplified for 2.13.9, as described here. The [earlier version](https://www.lightbend.com/blog/scala-inliner-optimizer) of this article uses the traditional forms, which are still supported. + ## Motivation -Why does the Scala compiler even have a JVM bytecode optimizer? The JVM is a highly optimized runtime with a just-in-time (JIT) compiler with 19 years of tuning. It's because there are certain well-known code patterns that the JVM fails to optimize properly. These patterns are common in functional languages such as Scala. (Increasingly, Java code with lambdas is catching up and showing the same performance issues at run-time.) +Why does the Scala compiler even have a JVM bytecode optimizer? The JVM is a highly optimized runtime with a just-in-time (JIT) compiler that benefits from over two decades of tuning. It's because there are certain well-known code patterns that the JVM fails to optimize properly. These patterns are common in functional languages such as Scala. (Increasingly, Java code with lambdas is catching up and showing the same performance issues at run-time.) The two most important such patterns are "megamorphic dispatch" (also called "the inlining problem") and value boxing. If you'd like to learn more about these problems in the context of Scala, you could watch the part of [my Scala Days 2015 talk (starting at 26:13)](https://youtu.be/Ic4vQJcYwsU?t=1573). The goal of the Scala optimizer is to produce bytecode that the JVM can execute fast. It is also a goal to avoid performing any optimizations that the JVM can already do well. -This means that the Scala optimizer may become obsolete in the future, if the JIT compiler is improved to handle these patterns better. In fact, with the arrival of GraalVM, that future might be nearer than you think! We take a closer look at Graal in a follow-up post. But for now, we dive into some details about the Scala optimizer. +This means that the Scala optimizer may become obsolete in the future, if the JIT compiler is improved to handle these patterns better. In fact, with the arrival of GraalVM, that future might be nearer than you think! But for now, we dive into some details about the Scala optimizer. ## Constraints and assumptions @@ -45,7 +55,7 @@ However, even when staying within these constraints, some changes performed by t - Inlined methods disappear from call stacks. - This can lead to unexpected behaviors when using a debugger. - - Related: line numbers (stored in bytecode) are discarded when a method is inlined into a different classfile, which also impacts debugging experience. (This [could be improved](https://github.com/scala/scala-dev/issues/3).) + - Related: line numbers (stored in bytecode) are discarded when a method is inlined into a different classfile, which also impacts debugging experience. (This [could be improved](https://github.com/scala/scala-dev/issues/3) and is expected to [progress](https://github.com/lampepfl/dotty/pull/11492).) - Inlining a method can delay class loading of the class where the method is defined. @@ -73,7 +83,7 @@ However, even when staying within these constraints, some changes performed by t ## Binary compatibility -Scala minor releases are binary compatible with each other, for example 2.12.6 and 2.12.7. The same is true for many libraries in the Scala ecosystem. These binary compatibility promises are the main reason for the Scala optimizer not to be enabled everywhere. +Scala minor releases are binary compatible with each other, for example, 2.12.6 and 2.12.7. The same is true for many libraries in the Scala ecosystem. These binary compatibility promises are the main reason for the Scala optimizer not to be enabled everywhere. The reason is that inlining a method from one class into another changes the (binary) interface that is accessed: @@ -112,25 +122,25 @@ The reason for this restriction is that dependency management tools like sbt wil The compiler flag for enabling the optimizer is `-opt`. Running `scalac -opt:help` shows how to use the flag. -By default (without any compiler flags, or with `-opt:l:default`), the Scala compiler eliminates unreachable code, but does not run any other optimizations. +By default (without any compiler flags, or with `-opt:default`), the Scala compiler eliminates unreachable code, but does not run any other optimizations. -`-opt:l:method` enables all method-local optimizations, for example: +`-opt:local` enables all method-local optimizations, for example: - Elimination of code that loads unused values - Rewriting of null and `isInstanceOf` checks whose result is known at compile-time - Elimination of value boxes like `java.lang.Integer` or `scala.runtime.DoubleRef` that are created within a method and don't escape it -Individual optimizations can be disabled. For example, `-opt:l:method,-nullness-tracking` disables nullness optimizations. +Individual optimizations can be disabled. For example, `-opt:local,-nullness-tracking` disables nullness optimizations. Method-local optimizations alone typically don't have any positive effect on performance, because source code usually doesn't have unnecessary boxing or null checks. However, local optimizations can often be applied after inlining, so it's really the combination of inlining and local optimizations that can improve program performance. -`-opt:l:inline` enables inlining in addition to method-local optimizations. However, to avoid unexpected binary compatibility issues, we also need to tell the compiler which code it is allowed to inline. This is done with the `-opt-inline-from` compiler flag. Examples: +`-opt:inline` enables inlining in addition to method-local optimizations. However, to avoid unexpected binary compatibility issues, we also need to tell the compiler which code it is allowed to inline. This is done by specifying a pattern after the option to select packages, classes, and methods for inlining. Examples: -- `-opt-inline-from:my.library.**` enables inlining from any class defined in package `my.library`, or in any of its sub-packages. Inlining within a library is safe for binary compatibility, so the resulting binary can be published. It will still work correctly even if one of its dependencies is updated to a newer minor version in the run-time classpath. -- `-opt-inline-from:` enables inlining from the set of source files being compiled in the current compiler invocation. This option can also be used for compiling libraries. If the source files of a library are split up across multiple sbt projects, inlining is only done within each project. Note that in an incremental compilation, inlining would only happen within the sources being re-compiled – but in any case, it is recommended to only enable the optimizer in CI and release builds (and to run `clean` before building). -- `-opt-inline-from:**` allows inlining from every class, including the JDK. This option enables full optimization when compiling an application. To avoid binary incompatibilities, it is mandatory to ensure that the run-time classpath is identical to the compile-time classpath, including the Java standard library. +- `-opt:inline:my.library.**` enables inlining from any class defined in package `my.library`, or in any of its sub-packages. Inlining within a library is safe for binary compatibility, so the resulting binary can be published. It will still work correctly even if one of its dependencies is updated to a newer minor version in the run-time classpath. +- `-opt-inline:`, where the pattern is the literal string ``, enables inlining from the set of source files being compiled in the current compiler invocation. This option can also be used for compiling libraries. If the source files of a library are split up across multiple sbt projects, inlining is only done within each project. Note that in an incremental compilation, inlining would only happen within the sources being re-compiled – but in any case, it is recommended to only enable the optimizer in CI and release builds (and to run `clean` before building). +- `-opt:inline:**` allows inlining from every class, including the JDK. This option enables full optimization when compiling an application. To avoid binary incompatibilities, it is mandatory to ensure that the run-time classpath is identical to the compile-time classpath, including the Java standard library. -Running `scalac -opt-inline-from:help` explains how to use the compiler flag. +Running `scalac -opt:help` explains how to use the compiler flag. ### Inliner heuristics and `@inline` @@ -163,11 +173,11 @@ Finally, note that the `@inline` annotation only has an effect when the inliner The inliner can issue warnings when callsites cannot be inlined. By default, these warnings are not issued individually, but only as a summary at the end of compilation (similar to deprecation warnings). ``` -$> scalac Test.scala -opt:l:inline '-opt-inline-from:**' +$> scalac Test.scala '-opt:inline:**' warning: there was one inliner warning; re-run enabling -opt-warnings for details, or try -help one warning found -$> scalac Test.scala -opt:l:inline '-opt-inline-from:**' -opt-warnings +$> scalac Test.scala '-opt:inline:**' -Wopt Test.scala:3: warning: C::f()I is annotated @inline but could not be inlined: The method is not final and may be overridden. def t = f @@ -187,11 +197,11 @@ object T extends C { } ``` -The `-opt-warnings` flag has more configurations. With `-opt-warnings:_`, a warning is issued for every callsite that is selected by the heuristic but cannot be inlined. See also `-opt-warnings:help`. +The `-Wopt` flag has more configurations. With `-Wopt:_`, a warning is issued for every callsite that is selected by the heuristic but cannot be inlined. See also `-Wopt:help`. ### Inliner log -If you're curious (or maybe even skeptical) about what the inliner is doing to your code, you can use the `-Yopt-log-inline` flag to produce a trace of the inliner's work: +If you're curious (or maybe even skeptical) about what the inliner is doing to your code, you can use the `-Vinline` verbose flag to produce a trace of the inliner's work: ```scala package my.project @@ -201,7 +211,7 @@ class C { ``` ``` -$> scalac Test.scala -opt:l:inline '-opt-inline-from:**' -Yopt-log-inline my/project/C.f +$> scalac Test.scala '-opt:inline:**' -Vinline my/project/C.f Inlining into my/project/C.f inlined scala/Predef$.intArrayOps (the callee is annotated `@inline`). Before: 15 ins, after: 30 ins. inlined scala/collection/ArrayOps$.map$extension (the callee is a higher-order method, the argument for parameter (evidence$6: Function1) is a function literal). Before: 30 ins, after: 94 ins. @@ -211,11 +221,3 @@ Inlining into my/project/C.f inlined my/project/C.$anonfun$f$1 (the callee is a synthetic forwarder method). Before: 654 ins, after: 666 ins. inlined scala/runtime/BoxesRunTime.boxToInteger (the callee is a forwarder method with boxing adaptation). Before: 666 ins, after: 674 ins. ``` - -Explaining the details here is out of scope for this post. We defer this discussion to a follow-up post that will explain the internals of the Scala optimizer in more detail. - -## Summary - -The goal of this article was to explain why the Scala optimizer exists and give a rough explanation what it can and cannot do. It also showed how to configure and use the optimizer in your project. - -In the next post, we will go into detail about how the optimizer works, what transformations are applied, and how they work together. We will also measure performance improvements that the optimizer can bring. Finally, we will look at related projects, dive a little more into the history of the optimizer, and discuss ideas for the future. From 3925a6475dfe3ff6ef0d25c319663d1117df31a9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 26 Feb 2022 02:56:40 +0000 Subject: [PATCH 1787/3075] Bump nokogiri from 1.12.5 to 1.13.3 Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.12.5 to 1.13.3. - [Release notes](https://github.com/sparklemotion/nokogiri/releases) - [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md) - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.12.5...v1.13.3) --- updated-dependencies: - dependency-name: nokogiri dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 0bbe4414f9..5b52d7697a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -54,9 +54,9 @@ GEM rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) mercenary (0.3.6) - mini_portile2 (2.6.1) - nokogiri (1.12.5) - mini_portile2 (~> 2.6.1) + mini_portile2 (2.8.0) + nokogiri (1.13.3) + mini_portile2 (~> 2.8.0) racc (~> 1.4) nokogumbo (2.0.2) nokogiri (~> 1.8, >= 1.8.4) @@ -64,7 +64,7 @@ GEM pathutil (0.16.2) forwardable-extended (~> 2.6) public_suffix (4.0.6) - racc (1.5.2) + racc (1.6.0) rainbow (3.0.0) rb-fsevent (0.11.0) rb-inotify (0.10.1) From 582e6c017de371609f54545b0e340fe4287cc22f Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Wed, 2 Mar 2022 07:06:41 -0800 Subject: [PATCH 1788/3075] Ruby 2.6 (was 2.5) --- .github/workflows/build.yml | 2 +- Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f9cca5b785..808f492a7d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,7 +8,7 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: 2.5.8 + ruby-version: 2.6.9 bundler-cache: true - name: Set up coursier uses: coursier/setup-action@v1.2.0-M2 diff --git a/Dockerfile b/Dockerfile index b972fe1c24..2fe3d70737 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ruby:2.5 +FROM ruby:2.6 RUN gem install bundler jekyll From b33f3a7d286db7aa3d3eb481b1997b5d1ce7388b Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Thu, 3 Mar 2022 02:46:11 -0800 Subject: [PATCH 1789/3075] Review and corrections --- _data/overviews.yml | 2 +- _overviews/compiler-options/optimizer.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/_data/overviews.yml b/_data/overviews.yml index ae56e9b5e9..a8bc055f7c 100644 --- a/_data/overviews.yml +++ b/_data/overviews.yml @@ -263,7 +263,7 @@ by: Lukas Rytz and Andrew Marki icon: cog url: "compiler-options/optimizer.html" - description: "The compiler can perform various optimizations as specified by compiler options." + description: "The compiler can perform various optimizations." - category: Legacy diff --git a/_overviews/compiler-options/optimizer.md b/_overviews/compiler-options/optimizer.md index 936967e8a0..cad7255280 100644 --- a/_overviews/compiler-options/optimizer.md +++ b/_overviews/compiler-options/optimizer.md @@ -3,9 +3,9 @@ layout: singlepage-overview title: Optimizer --- -**[Lukas Rytz](https://github.com/lrytz) (November 7, 2018)** +**[Lukas Rytz](https://github.com/lrytz) (2018)** -**[Andrew Marki](https://github.com/som-snytt) (February 29, 2022)** +**[Andrew Marki](https://github.com/som-snytt) (2022)** # The Scala 2.12 / 2.13 Inliner and Optimizer @@ -114,7 +114,7 @@ This means that `m` can be inlined into classes other than `C`, since the result Even more trivially, assume that method `m` was buggy and is changed to `def m = if (fullMoon) 1 else x` in a minor release. Normally, it would be enough for a user to put the new version on the classpath. However, if the old version of `c.m` was inlined at compile-time, having the new version of C on the run-time classpath would not fix the bug. -In order to safely use the Scala optimizer, users need to make sure that the compile-time and run-time classpaths are identical. This has a far-reaching consequence for library developers: **libraries that are published to be consumed by other projects should not inline code from the classpath**. The inliner can be configured to inline code from the library itself using `-opt-inline-from:my.package.**`. +In order to safely use the Scala optimizer, users need to make sure that the compile-time and run-time classpaths are identical. This has a far-reaching consequence for library developers: **libraries that are published to be consumed by other projects should not inline code from the classpath**. The inliner can be configured to inline code from the library itself using `-opt:inline:my.package.**`. The reason for this restriction is that dependency management tools like sbt will often pick newer versions of transitive dependencies. For example, if library `A` depends on `core-1.1.1`, `B` depends on `core-1.1.2` and the application depends on both `A` and `B`, the build tool will put `core-1.1.2` on the classpath. If code from `core-1.1.1` was inlined into `A` at compile-time, it might break at run-time due to a binary incompatibility. @@ -137,7 +137,7 @@ Method-local optimizations alone typically don't have any positive effect on per `-opt:inline` enables inlining in addition to method-local optimizations. However, to avoid unexpected binary compatibility issues, we also need to tell the compiler which code it is allowed to inline. This is done by specifying a pattern after the option to select packages, classes, and methods for inlining. Examples: - `-opt:inline:my.library.**` enables inlining from any class defined in package `my.library`, or in any of its sub-packages. Inlining within a library is safe for binary compatibility, so the resulting binary can be published. It will still work correctly even if one of its dependencies is updated to a newer minor version in the run-time classpath. -- `-opt-inline:`, where the pattern is the literal string ``, enables inlining from the set of source files being compiled in the current compiler invocation. This option can also be used for compiling libraries. If the source files of a library are split up across multiple sbt projects, inlining is only done within each project. Note that in an incremental compilation, inlining would only happen within the sources being re-compiled – but in any case, it is recommended to only enable the optimizer in CI and release builds (and to run `clean` before building). +- `-opt:inline:`, where the pattern is the literal string ``, enables inlining from the set of source files being compiled in the current compiler invocation. This option can also be used for compiling libraries. If the source files of a library are split up across multiple sbt projects, inlining is only done within each project. Note that in an incremental compilation, inlining would only happen within the sources being re-compiled – but in any case, it is recommended to only enable the optimizer in CI and release builds (and to run `clean` before building). - `-opt:inline:**` allows inlining from every class, including the JDK. This option enables full optimization when compiling an application. To avoid binary incompatibilities, it is mandatory to ensure that the run-time classpath is identical to the compile-time classpath, including the Java standard library. Running `scalac -opt:help` explains how to use the compiler flag. @@ -174,7 +174,7 @@ The inliner can issue warnings when callsites cannot be inlined. By default, the ``` $> scalac Test.scala '-opt:inline:**' -warning: there was one inliner warning; re-run enabling -opt-warnings for details, or try -help +warning: there was one inliner warning; re-run enabling -Wopt for details, or try -help one warning found $> scalac Test.scala '-opt:inline:**' -Wopt From 5ab2ddda467ac4b3228338002648c0315da28269 Mon Sep 17 00:00:00 2001 From: Brian Yue Date: Sat, 5 Mar 2022 12:19:04 +0800 Subject: [PATCH 1790/3075] Fix invalid links --- _overviews/scaladoc/contribute.md | 2 +- _scala3-reference/other-new-features/explicit-nulls.md | 2 +- scala3/scaladoc.md | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/_overviews/scaladoc/contribute.md b/_overviews/scaladoc/contribute.md index c902e99f97..dc0af2ce57 100644 --- a/_overviews/scaladoc/contribute.md +++ b/_overviews/scaladoc/contribute.md @@ -25,4 +25,4 @@ which covers the steps and workflow necessary work on the Scaladoc tool. As of Scala 2.13, the Scaladoc tool is maintained but not actively developed. Major development of Scaladoc will progress as a part of Dotty for Scala 3 in the -[Dottydoc](https://dotty.epfl.ch/docs/usage/dottydoc.html) tool. +[Scaladoc]({% link _overviews/scala3-scaladoc/index.md %}) tool. diff --git a/_scala3-reference/other-new-features/explicit-nulls.md b/_scala3-reference/other-new-features/explicit-nulls.md index a0dac187ae..d33d86c931 100644 --- a/_scala3-reference/other-new-features/explicit-nulls.md +++ b/_scala3-reference/other-new-features/explicit-nulls.md @@ -537,4 +537,4 @@ Our strategy for binary compatibility with Scala binaries that predate explicit and new libraries compiled without `-Yexplicit-nulls` is to leave the types unchanged and be compatible but unsound. -[More details](https://dotty.epfl.ch/docs/internals/explicit-nulls.html) +[More details](https://dotty.epfl.ch/3.0.0/docs/internals/explicit-nulls.html) diff --git a/scala3/scaladoc.md b/scala3/scaladoc.md index 69c307654e..3b8e90b7d8 100644 --- a/scala3/scaladoc.md +++ b/scala3/scaladoc.md @@ -79,7 +79,7 @@ For more information see [Guides](/scala3/guides/scaladoc/search-engine.html) Note that this feature is still in development, so it can be subject to considerable change. If you encounter a bug or have an idea for improvement, don't hesitate to create an issue on [Inkuire](https://github.com/VirtusLab/Inkuire/issues/new) or [dotty](https://github.com/lampepfl/dotty/issues/new). -[scaladoc-docstrings]: https://dotty.epfl.ch/docs/usage/scaladoc/docstrings.html -[static-documentation]: https://dotty.epfl.ch/docs/usage/scaladoc/static-site.html -[built-in-blog]: https://dotty.epfl.ch/docs/usage/scaladoc/blog.html +[scaladoc-docstrings]: {% link _overviews/scala3-scaladoc/docstrings.md %} +[static-documentation]: {% link _overviews/scala3-scaladoc/static-site.md %} +[built-in-blog]: {% link _overviews/scala3-scaladoc/blog.md %} [social-links]: https://dotty.epfl.ch/docs/usage/scaladoc/settings.html#-social-links From 821446e2eb2ed77a39e0839698f821b5e5051562 Mon Sep 17 00:00:00 2001 From: Brian Yue Date: Fri, 4 Mar 2022 22:47:25 +0800 Subject: [PATCH 1791/3075] [zh-cn] Scala 3 Features --- _zh-cn/overviews/scala3-book/introduction.md | 12 +- .../overviews/scala3-book/scala-features.md | 891 ++++++++++++++++++ 2 files changed, 897 insertions(+), 6 deletions(-) create mode 100644 _zh-cn/overviews/scala3-book/scala-features.md diff --git a/_zh-cn/overviews/scala3-book/introduction.md b/_zh-cn/overviews/scala3-book/introduction.md index 158c93df11..21d8562dc2 100644 --- a/_zh-cn/overviews/scala3-book/introduction.md +++ b/_zh-cn/overviews/scala3-book/introduction.md @@ -4,7 +4,7 @@ type: chapter description: This page begins the overview documentation of the Scala 3 language. num: 1 previous-page: -next-page: +next-page: scala-features scala3: true partof: scala3-book @@ -14,13 +14,13 @@ permalink: "/zh-cn/scala3/book/:title.html" --- 欢迎阅读《Scala 3》一书。 -本书的目标是提供对Scala语言的非正式介绍,并以相对轻松的方式涉及所有的Scala主题。 -若您在阅读本书时想了解有关特定功能的更多信息,可以随时参阅[_参考文档_][reference],其中更详细地涵盖了Scala语言的许多新特性。 +本书的目标是提供对 Scala 语言的非正式介绍,并以相对轻松的方式涉及所有的 Scala 主题。 +若您在阅读本书时想了解有关特定功能的更多信息,可以随时参阅[_参考文档_][reference],其中更详细地涵盖了 Scala 语言的许多新特性。 -在本书中,我们希望证明Scala是一种优美的、富有表现力的编程语言。它具有简洁、现代的语法,支持函数式编程(FP)和面向对象编程(OOP),并提供安全的静态类型系统。 -Scala的语法和特性都经过了重新思考与公开辩论,并在2020年更新,比以往任何时候都更清晰、更容易理解。 +在本书中,我们希望证明 Scala 是一种优美的、富有表现力的编程语言。它具有简洁、现代的语法,支持函数式编程(FP)和面向对象编程(OOP),并提供安全的静态类型系统。 +Scala 的语法和特性都经过了重新思考与公开辩论,并在2020年更新,比以往任何时候都更清晰、更容易理解。 -本书首先在[“品味Scala”部分][taste]对Scala的许多特性进行了一次“旋风之旅”。随后的章节会提供有关这些语言特性的更多详细信息。 +本书首先在[“品味 Scala”部分][taste]对 Scala 的许多特性进行了一次“旋风之旅”。随后的章节会提供有关这些语言特性的更多详细信息。 > 我们仍在撰写本书的过程中。 > 您可以[帮助我们改进][contributing] diff --git a/_zh-cn/overviews/scala3-book/scala-features.md b/_zh-cn/overviews/scala3-book/scala-features.md new file mode 100644 index 0000000000..394681e1cf --- /dev/null +++ b/_zh-cn/overviews/scala3-book/scala-features.md @@ -0,0 +1,891 @@ +--- +title: Scala 3 特性 +type: chapter +description: This page discusses the main features of the Scala 3 programming language. +num: 2 +previous-page: introduction +next-page: + +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +layout: multipage-overview +permalink: "/zh-cn/scala3/book/:title.html" +--- + +{% comment %} +The name _Scala_ comes from the word _scalable_, and true to that name, the Scala language is used to power busy websites and analyze huge data sets. +This section introduces the features that make Scala a scalable language. +These features are split into three sections: +{% endcomment %} + +_Scala_ 这个名字来源于 _scalable_ 一词。正如其名,Scala 语言被用于支撑高流量网站以及分析庞大的数据集。 +本节介绍了使 Scala 成为一门可扩展语言的特性。 +这些特性分为三个部分: + +{% comment %} + +- High-level language features +- Lower-level language features +- Scala ecosystem features + +{% endcomment %} + +- 高级语言特性 +- 底层语言特性 +- Scala 生态系统特性 + +{% comment %} +I think of this section as being like an “elevator pitch.” +{% endcomment %} + +{% comment %} + +## High-level features + +{% endcomment %} + +## 高级特性 + +{% comment %} +Looking at Scala from the proverbial “30,000 foot view,” you can make the following statements about it: +{% endcomment %} + +从宏观视角来看 Scala,您可以对它做出以下陈述: + +{% comment %} + +- It’s a high-level programming language +- It has a concise, readable syntax +- It’s statically-typed (but feels dynamic) +- It has an expressive type system +- It’s a functional programming (FP) language +- It’s an object-oriented programming (OOP) language +- It supports the fusion of FP and OOP +- Contextual abstractions provide a clear way to implement _term inference_ +- It runs on the JVM (and in the browser) +- It interacts seamlessly with Java code +- It’s used for server-side applications (including microservices), big data applications, and can also be used in the browser with Scala.js + +{% endcomment %} + +- 它是一种高级编程语言 +- 它具有简明易读的语法 +- 它是静态类型的(但使人感觉是动态的) +- 它有一个表达力强大的类型系统 +- 它是一种函数式编程(FP)语言 +- 它是一种面向对象的编程(OOP)语言 +- 它支持 FP 与 OOP 的融合 +- 上下文抽象提供了一种清晰的方式来实现 _表达式推断_ +- 它在 JVM(和浏览器)上运行 +- 它与 Java 代码无缝交互 +- 它可被用于服务器端应用(包括微服务)、大数据应用,也可以在浏览器中与 Scala.js 共同使用 + +{% comment %} +The following sections take a quick look at these features. +{% endcomment %} + +以下部分将对这些特性进行简要介绍。 + +{% comment %} + +### A high-level language + +{% endcomment %} + +### 一门高级语言 + +{% comment %} +Scala is considered a high-level language in at least two ways. +First, like Java and many other modern languages, you don’t deal with low-level concepts like pointers and memory management. +{% endcomment %} + +Scala 至少在两个方面被认为是一门高级语言。 +首先,像 Java 和许多其他现代语言一样,您不需要与指针和内存管理等底层概念打交道。 + +{% comment %} +Second, with the use of lambdas and higher-order functions, you write your code at a very high level. +As the functional programming saying goes, in Scala you write _what_ you want, not _how_ to achieve it. +That is, we don’t write imperative code like this: +{% endcomment %} + +其次,通过使用 lambda 与高阶函数,您可以在非常高的层次上编写代码。 +正如函数式编程的说法,在 Scala 中,您编写您想要 _“什么”_,而不是 _“如何”_ 去实现它。 +也就是说,我们不会像这样编写命令式代码: + +```scala +def double(ints: List[Int]): List[Int] = { + val buffer = new ListBuffer[Int]() + for (i <- ints) { + buffer += i * 2 + } + buffer.toList +} + +val newNumbers = double(oldNumbers) +``` + +{% comment %} +That code instructs the compiler what to do on a step-by-step basis. +Instead, we write high-level, functional code using higher-order functions and lambdas like this to compute the same result: +{% endcomment %} + +这段代码指示编译器逐步执行特定操作。 +相反,我们使用像这样的高阶函数与 lambda 来编写高层次的函数式代码以计算出相同的结果: + +```scala +val newNumbers = oldNumbers.map(_ * 2) +``` + +{% comment %} +As you can see, that code is much more concise, easier to read, and easier to maintain. +{% endcomment %} + +如您所见,该代码更简洁、更容易阅读且更易于维护。 + +{% comment %} + +### Concise syntax + +{% endcomment %} + +### 简明的语法 + +{% comment %} +Scala has a concise, readable syntax. +For instance, variables are created concisely, and their types are clear: +{% endcomment %} + +Scala 具有简明易读的语法。例如,变量的创建十分简洁,其类型也很明确。 + +```scala +val nums = List(1,2,3) +val p = Person("Martin", "Odersky") +``` + +{% comment %} +Higher-order functions and lambdas make for concise code that’s readable: +{% endcomment %} + +高阶函数与 lambda 使代码简明易读: + +```scala +nums.map(i => i * 2) // long form +nums.map(_ * 2) // short form + +nums.filter(i => i > 1) +nums.filter(_ > 1) +``` + +{% comment %} +Traits, classes, and methods are defined with a clean, light syntax: +{% endcomment %} + +特质(Traits)、类(Class)和方法(Method)都是用简洁、轻巧的语法定义的。 + +```scala +trait Animal: + def speak(): Unit + +trait HasTail: + def wagTail(): Unit + +class Dog extends Animal, HasTail: + def speak() = println("Woof") + def wagTail() = println("⎞⎜⎛ ⎞⎜⎛") +``` + +{% comment %} +Studies have shown that the time a developer spends _reading_ code to _writing_ code is at least a 10:1 ratio, so writing code that is concise _and_ readable is important. +{% endcomment %} + +研究表明,开发人员花在 _阅读_ 代码和 _编写_ 代码上的时间比例至少为 10:1。因此,编写简洁 _并_ 易读的代码非常重要。 + +{% comment %} + +### A dynamic feel + +{% endcomment %} + +### 动态感受 + +{% comment %} +Scala is a statically-typed language, but thanks to its type inference capabilities it feels dynamic. +All of these expressions look like a dynamically-typed language like Python or Ruby, but they’re all Scala: +{% endcomment %} + +Scala 是一种静态类型的语言,但由于其类型推断能力,它使人感觉是动态的。所有这些表达式看起来都像 Python 或 Ruby 这样的动态类型语言代码,但其实它们都是 Scala 代码: + +```scala +val s = "Hello" +val p = Person("Al", "Pacino") +val sum = ints.reduceLeft(_ + _) +val y = for i <- nums yield i * 2 +val z = nums.filter(_ > 100) + .filter(_ < 10_000) + .map(_ * 2) +``` + +{% comment %} +As Heather Miller states, Scala is considered to be a [strong, statically-typed language](https://heather.miller.am/blog/types-in-scala.html), and you get all the benefits of static types: +{% endcomment %} + +正如 Heather Miller 所说,Scala 被认为是一种[强静态类型语言](https://heather.miller.am/blog/types-in-scala.html)。您可以获得静态类型的全部益处: + +{% comment %} + +- Correctness: you catch most errors at compile-time +- Great IDE support + - Reliable code completion + - Catching errors at compile-time means catching mistakes as you type + - Easy and reliable refactoring +- You can refactor your code with confidence +- Method type declarations tell readers what the method does, and help serve as documentation +- Scalability and maintainability: types help ensure correctness across arbitrarily large applications and development teams +- Strong typing in combination with excellent inference enables mechanisms like [contextual abstraction]({{ site.scala3ref }}/contextual.html) that allows you to omit boilerplate code. Often, this boilerplate code can be inferred by the compiler, based on type definitions and a given context. + +{% endcomment %} + +- 正确性:您可以在编译时捕获大多数错误 +- 强大的 IDE 支持 + - 可靠的代码补全 + - 在编译时捕获错误意味着在您打字时捕获错误 + - 简单而可靠的重构 +- 您可以自信地重构您的代码 +- 方法类型声明告诉读者该方法的作用,并作为文档提供帮助 +- 可扩展性与可维护性:类型有助于在任意大小的应用程序与开发团队中确保正确性 +- 强类型结合优秀的推断能力可实现[上下文抽象]({{ site.scala3ref }}/contextual.html)等机制,这允许您省略样板代码。通常,这些样板代码可由编译器根据类型定义及给定的上下文推断出来。 + +{% comment %} +In that list: +- 'Correctness' and 'Scalability' come from Heather Miller’s page +- the IDE-related quotes in this section come from the Scala.js website: + - catch most errors in the IDE + - Easy and reliable refactoring + - Reliable code completion +{% endcomment %} + +{% comment %} + +### Expressive type system + +{% endcomment %} + +### 富有表现力的类型系统 + +{% comment %} +- this text comes from the current [ScalaTour](https://docs.scala-lang.org/tour/tour-of-scala.html). +- TODO: all of the URLs will have to be updated + +- i removed these items until we can replace them: +* [Compound types](/tour/compound-types.html) +* [conversions](/tour/implicit-conversions.html) +* [Explicitly typed self references](/tour/self-types.html) +{% endcomment %} + +{% comment %} +Scala’s type system enforces, at compile-time, that abstractions are used in a safe and coherent manner. +In particular, the type system supports: +{% endcomment %} + +Scala 的类型系统在编译时强制要求以安全与连贯的方式使用抽象概念。特别是,该类型系统支持: + +{% comment %} +- [Inferred types]({% link _overviews/scala3-book/types-inferred.md %}) +- [Generic classes]({% link _overviews/scala3-book/types-generics.md %}) +- [Variance annotations]({% link _overviews/scala3-book/types-variance.md %}) +- [Upper](/tour/upper-type-bounds.html) and [lower](/tour/lower-type-bounds.html) type bounds +- [Polymorphic methods](/tour/polymorphic-methods.html) +- [Intersection types]({% link _overviews/scala3-book/types-intersection.md %}) +- [Union types]({% link _overviews/scala3-book/types-union.md %}) +- [Type lambdas]({{ site.scala3ref }}/new-types/type-lambdas.html) +- [`given` instances and `using` clauses]({% link _overviews/scala3-book/ca-given-using-clauses.md %}) +- [Extension methods]({% link _overviews/scala3-book/ca-extension-methods.md %}) +- [Type classes]({% link _overviews/scala3-book/ca-type-classes.md %}) +- [Multiversal equality]({% link _overviews/scala3-book/ca-multiversal-equality.md %}) +- [Opaque type aliases]({% link _overviews/scala3-book/types-opaque-types.md %}) +- [Open classes]({{ site.scala3ref }}/other-new-features/open-classes.html) +- [Match types]({{ site.scala3ref }}/new-types/match-types.html) +- [Dependent function types]({{ site.scala3ref }}/new-types/dependent-function-types.html) +- [Polymorphic function types]({{ site.scala3ref }}/new-types/polymorphic-function-types.html) +- [Context bounds]({{ site.scala3ref }}/contextual/context-bounds.html) +- [Context functions]({{ site.scala3ref }}/contextual/context-functions.html) +- [Inner classes](/tour/inner-classes.html) and [abstract type members](/tour/abstract-type-members.html) as object members +{% endcomment %} + +- [推断类型]({% link _overviews/scala3-book/types-inferred.md %}) +- [泛型类]({% link _overviews/scala3-book/types-generics.md %}) +- [型变]({% link _overviews/scala3-book/types-variance.md %}) +- [类型上界](/tour/upper-type-bounds.html) 与 [类型下界](/tour/lower-type-bounds.html) +- [多态方法](/tour/polymorphic-methods.html) +- [交叉类型]({% link _overviews/scala3-book/types-intersection.md %}) +- [联合类型]({% link _overviews/scala3-book/types-union.md %}) +- [类型 Lambda]({{ site.scala3ref }}/new-types/type-lambdas.html) +- [`given` 实例与 `using` 子句]({% link _overviews/scala3-book/ca-given-using-clauses.md %}) +- [扩展方法]({% link _overviews/scala3-book/ca-extension-methods.md %}) +- [类型类]({% link _overviews/scala3-book/ca-type-classes.md %}) +- [多元相等]({% link _overviews/scala3-book/ca-multiversal-equality.md %}) +- [不透明类型别名]({% link _overviews/scala3-book/types-opaque-types.md %}) +- [开放类]({{ site.scala3ref }}/other-new-features/open-classes.html) +- [匹配类型]({{ site.scala3ref }}/new-types/match-types.html) +- [依赖函数类型]({{ site.scala3ref }}/new-types/dependent-function-types.html) +- [多态函数类型]({{ site.scala3ref }}/new-types/polymorphic-function-types.html) +- [上下文边界]({{ site.scala3ref }}/contextual/context-bounds.html) +- [上下文函数]({{ site.scala3ref }}/contextual/context-functions.html) +- 作为对象成员的[内部类](/tour/inner-classes.html) 与 [抽象类型](/tour/abstract-type-members.html) + +{% comment %} +In combination, these features provide a powerful basis for the safe reuse of programming abstractions and for the type-safe extension of software. +{% endcomment %} + +通过结合使用,这些特性为编程抽象的安全重用及软件的类型安全扩展提供了强大的基础。 + +{% comment %} + +### A functional programming language + +{% endcomment %} + +### 一门函数式编程语言 + +{% comment %} +Scala is a functional programming (FP) language, meaning: +{% endcomment %} + +Scala 是一门函数式编程(FP)语言,也就是说: + +{% comment %} + +- Functions are values, and can be passed around like any other value +- Higher-order functions are directly supported +- Lambdas are built in +- Everything in Scala is an expression that returns a value +- Syntactically it’s easy to use immutable variables, and their use is encouraged +- It has a wealth of immutable collection classes in the standard library +- Those collection classes come with dozens of functional methods: they don’t mutate the collection, but instead return an updated copy of the data + +{% endcomment %} + +- 函数是值,可以像任何其他值一样被传递 +- 直接支持高阶函数 +- 原生地支持 Lambda +- Scala 中的一切都是会返回值的表达式 +- 从语法上来说,使用不可变变量很容易并且此行为被鼓励 +- 在标准库中有大量的不可变集合类 +- 这些集合类带有许多函数式方法:它们不改变集合本身,而是返回数据的更新副本 + +{% comment %} + +### An object-oriented language + +{% endcomment %} + +### 一门面向对象语言 + +{% comment %} +Scala is an object-oriented programming (OOP) language. +Every value is an instance of a class and every “operator” is a method. +{% endcomment %} + +Scala 是一门面向对象编程(OOP)语言。 +每个值都是一个类的实例,每个“运算符”都是一个方法。 + +{% comment %} +In Scala, all types inherit from a top-level class `Any`, whose immediate children are `AnyVal` (_value types_, such as `Int` and `Boolean`) and `AnyRef` (_reference types_, as in Java). +This means that the Java distinction between primitive types and boxed types (e.g. `int` vs. `Integer`) isn’t present in Scala. +Boxing and unboxing is completely transparent to the user. +{% endcomment %} + +在 Scala 中,所有类型都继承自顶层类 `Any`,其直接子类是 `AnyVal`(_值类型_,例如 `Int` 与 `Boolean`)和 `AnyRef`(_引用类型_,与 Java 中相同)。 +这意味着 Scala 中不存在 Java 中原始类型和包装类型的区别(例如 `int` 与 `Integer`)。 +装箱与拆箱对用户来说是完全透明的。 + +{% comment %} +- AnyRef above is wrong in case of strict null checking, no? On the other hand, maybe too much information to state this here +- probably not worth to mention (too advanced at this point) there is AnyKind +- Add the “types hierarchy” image here? +{% endcomment %} + +{% comment %} + +### Supports FP/OOP fusion + +{% endcomment %} + +### 支持 FP 与 OOP 融合 + +{% comment %} +NOTE: This text in the first line comes from this slide: https://twitter.com/alexelcu/status/996408359514525696 +{% endcomment %} + +{% comment %} +The essence of Scala is the fusion of functional programming and object-oriented programming in a typed setting: + +- Functions for the logic +- Objects for the modularity + +As [Martin Odersky has stated](https://jaxenter.com/current-state-scala-odersky-interview-129495.html), “Scala was designed to show that a fusion of functional and object-oriented programming is possible and practical.” +{% endcomment %} + +Scala 的本质是函数式编程和面向对象编程的融合: + +- 函数用于代表逻辑 +- 对象用于模块化 + +正如 [Martin Odersky 所说](https://jaxenter.com/current-state-scala-odersky-interview-129495.html),“Scala 旨在表明函数式编程与面向对象编程的融合是切实可行的。” + +{% comment %} + +### Term inference, made clearer + +{% endcomment %} + +### 表达式推断,更加清晰 + +{% comment %} +Following Haskell, Scala was the second popular language to have some form of _implicits_. +In Scala 3 these concepts have been completely re-thought and more clearly implemented. + +The core idea is _term inference_: Given a type, the compiler synthesizes a “canonical” term that has that type. +In Scala, a context parameter directly leads to an inferred argument term that could also be written down explicitly. + +Use cases for this concept include implementing [type classes]({% link _overviews/scala3-book/ca-type-classes.md %}), establishing context, dependency injection, expressing capabilities, computing new types, and proving relationships between them. + +Scala 3 makes this process more clear than ever before. +Read about contextual abstractions in the [Reference documentation]({{ site.scala3ref }}/contextual.html). +{% endcomment %} + +继 Haskell 之后,Scala 是第二种具有某种形式的 _隐式_ 的流行语言。 +在 Scala 3 中,这些概念经过了重新考虑并更清晰地实现。 + +其核心思想是 _表达式推断_:给定一个类型,编译器会合成一个具有该类型的“规范”表达式。 +在 Scala 中,一个上下文参数直接导致一个被推断出的参数项的出现。该参数项也可以被显式地写出来。 + +此概念的用例包括实现[类型类]({% link _overviews/scala3-book/ca-type-classes.md %})、建立上下文、依赖注入、表达能力、计算新类型以及证明它们之间的关系。 + +Scala 3 使此过程比以往任何时候都更加清晰。 +请在[参考文档]({{ site.scala3ref }}/contextual.html)中阅读关于上下文抽象的内容。 + +{% comment %} + +### Client & server + +{% endcomment %} + +### 客户端与服务器 + +{% comment %} +Scala code runs on the Java Virtual Machine (JVM), so you get all of its benefits: + +- Security +- Performance +- Memory management +- Portability and platform independence +- The ability to use the wealth of existing Java and JVM libraries + +In addition to running on the JVM, Scala also runs in the browser with Scala.js (and open source third-party tools to integrate popular JavaScript libraries), and native executables can be built with Scala Native and GraalVM. +{% endcomment %} + +Scala 代码在 Java 虚拟机(JVM)上运行,因此您可以获得它的全部益处: + +- 安全性 +- 性能 +- 内存管理 +- 可移植性与平台独立性 +- 能够使用大量的现有 Java 和 JVM 库 + +除了在 JVM 上运行外,Scala 还可以通过 Scala.js (以及开源的第三方工具以集成流行的 JavaScript 库)在浏览器中运行,并且可以使用Scala Native 与 GraalVM 构建原生可执行文件。 + +{% comment %} + +### Seamless Java interaction + +{% endcomment %} + +### 与 Java 无缝交互 + +{% comment %} +You can use Java classes and libraries in your Scala applications, and you can use Scala code in your Java applications. +In regards to the second point, large libraries like [Akka](https://akka.io) and the [Play Framework](https://www.playframework.com) are written in Scala, and can be used in Java applications. +{% endcomment %} + +您可以在 Scala 应用程序中使用 Java 类和库,也可以在 Java 应用程序中使用 Scala 代码。 +对于第二点来说,诸如 [Akka](https://akka.io) 和 [Play Framework](https://www.playframework.com) 之类的大型库是用 Scala 编写的,并且它们可以在 Java 应用程序中使用。 + +{% comment %} +In regards to the first point, Java classes and libraries are used in Scala applications every day. +For instance, in Scala you can read files with a Java `BufferedReader` and `FileReader`: +{% endcomment %} + +对于第一点来说,Scala 应用程序中每天都会用到 Java 类和库。 +例如,在 Scala 中,您可以使用 Java 的 `BufferedReader` 和 `FileReader` 来读取文件: + +```scala +import java.io.* +val br = BufferedReader(FileReader(filename)) +// read the file with `br` ... +``` + +{% comment %} +Using Java code in Scala is generally seamless. + +Java collections can also be used in Scala, and if you want to use Scala’s rich collection class methods with them, you can convert them with just a few lines of code: +{% endcomment %} + +在 Scala 中使用 Java 代码通常是无缝衔接的。 + +Java 集合也可以在 Scala 中使用, 如果您想将 Scala 丰富的集合类方法与其一起使用,只需几行代码即可转换它们: + + +```scala +import scala.jdk.CollectionConverters.* +val scalaList: Seq[Integer] = JavaClass.getJavaList().asScala.toSeq +``` + +{% comment %} + +### Wealth of libraries + +{% endcomment %} + +### 丰富的库 + +{% comment %} +As you’ll see in the third section of this page, Scala libraries and frameworks like these have been written to power busy websites and work with huge datasets: + +1. The [Play Framework](https://www.playframework.com) is a lightweight, stateless, developer-friendly, web-friendly architecture for creating highly-scalable applications +2. [Lagom](https://www.lagomframework.com) is a microservices framework that helps you decompose your legacy monolith and build, test, and deploy entire systems of reactive microservices +3. [Apache Spark](https://spark.apache.org) is a unified analytics engine for big data processing, with built-in modules for streaming, SQL, machine learning and graph processing + +The [Awesome Scala list](https://github.com/lauris/awesome-scala) shows dozens of additional open source tools that developers have created to build Scala applications. + +In addition to server-side programming, [Scala.js](https://www.scala-js.org) is a strongly-typed replacement for writing JavaScript, with open source third-party libraries that include tools to integrate with Facebook’s React library, jQuery, and more. +{% endcomment %} + +正如您将在本页的第三部分中所看到的那样,已经有诸如此类的 Scala 库和框架被编写出来用于支撑高流量网站以及分析庞大的数据集: + +1. [Play Framework](https://www.playframework.com) 是一种用于创建高度可扩展应用程序的轻量级、无状态、对开发者及Web友好的架构 +2. [Lagom](https://www.lagomframework.com) 是一种微服务框架,可帮助您分解遗留的单体应用并构建、测试和部署整个响应式微服务系统 +3. [Apache Spark](https://spark.apache.org) 是一种面向大规模数据处理的统一分析引擎,内置流、SQL、机器学习和图形处理等模块 + +[Awesome Scala 列表](https://github.com/lauris/awesome-scala)展示了开发人员为构建 Scala 应用程序而创建的许多其他开源工具。 + +除了服务器端编程之外,[Scala.js](https://www.scala-js.org) 是一款用于编写 JavaScript 应用的强类型替代方案。其开源的第三方库包含支持与 Facebook 的 React、jQuery 及其他库等集成的工具。 + +{% comment %} +The Lower-Level Features section is like the second part of an elevator pitch. +Assuming you told someone about the previous high-level features and then they say, “Tell me more,” this is what you might tell them. +{% endcomment %} + +{% comment %} + +## Lower-level language features + +{% endcomment %} + +## 底层语言特性 + +{% comment %} +Where the previous section covered high-level features of Scala 3, it’s interesting to note that at a high level you can make the same statements about both Scala 2 and Scala 3. +A decade ago Scala started with a strong foundation of desirable features, and as you’ll see in this section, those benefits have been improved with Scala 3. +{% endcomment %} + +上一节介绍了 Scala 3 的高级特性,有趣的是,您可以从高层次上对 Scala 2 和 Scala 3 作出相同的表述。 +十年前,Scala 就为各种理想特性打下了坚实基础,正如您在本节中即将看到的那样,这些效益在 Scala 3 中得到了提高。 + +{% comment %} +At a “sea level” view of the details---i.e., the language features programmers use everyday---Scala 3 has significant advantages over Scala 2: + +- The ability to create algebraic data types (ADTs) more concisely with enums +- An even more concise and readable syntax: + - The “quiet” control structure syntax is easier to read + - Optional braces + - Fewer symbols in the code creates less visual noise, making it easier to read + - The `new` keyword is generally no longer needed when creating class instances + - The formality of package objects have been dropped in favor of simpler “top level” definitions +- A grammar that’s more clear: + - Multiple different uses of the `implicit` keyword have been removed; those uses are replaced by more obvious keywords like `given`, `using`, and `extension`, focusing on intent over mechanism (see the [Givens][givens] section for details) + - [Extension methods][extension] replace implicit classes with a clearer and simpler mechanism + - The addition of the `open` modifier for classes makes the developer intentionally declare that a class is open for modification, thereby limiting ad-hoc extensions to a code base + - [Multiversal equality][multiversal] rules out nonsensical comparisons with `==` and `!=` (i.e., attempting to compare a `Person` to a `Planet`) + - Macros are implemented much more easily + - Union and intersection offer a flexible way to model types + - Trait parameters replace and simplify early initializers + - [Opaque type aliases][opaque_types] replace most uses of value classes, while guaranteeing the absence of boxing + - Export clauses provide a simple and general way to express aggregation, which can replace the previous facade pattern of package objects inheriting from classes + - The procedure syntax has been dropped, and the varargs syntax has been changed, both to make the language more consistent + - The `@infix` annotation makes it obvious how you want a method to be applied + - The [`@targetName`]({{ site.scala3ref }}/other-new-features/targetName.html) method annotation defines an alternate name for the method, improving Java interoperability, and letting you provide aliases for symbolic operators + +It would take too much space to demonstrate all of those features here, but follow the links in the items above to see those features in action. +All of these features are discussed in detail in the *New*, *Changed*, and *Dropped* features pages in the [Overview documentation][reference]. +{% endcomment %} + +以小见大,从程序员日常使用的语言特性来看,Scala 3 比 Scala 2 具有显著优势: + +- 可以用枚举更简洁地创建代数数据类型(ADT) +- 更简明易读的语法: + - “干净”的控制结构语法更容易阅读 + - 可选的大括号 + - 代码中包含更少的符号,因此会产生更少的视觉噪音,使其更容易阅读 + - 创建类实例时一般不再需要 `new` 关键字 + - 弃用了包对象,转而使用更简单的“顶层”定义 +- 更清晰的语法: + - 移除了 `implicit` 关键字的多种不同用法,这些用法被更显而易见的关键字所取代,如 `given`、 `using`、和 `extension`,以此将关注重点放在意图而不是机制上(详见 [Givens][givens] 部分) + - [扩展方法][extension]通过更加清晰简单的机制取代了隐式类 + - 为类添加了 `open` 修饰符,使开发者能够有意识地声明一个类是可以被修改的,从而限制对代码库的临时扩展 + - [多元相等][multiversal]排除了用 `==` 和 `!=` 进行无意义的比较(即试图将 `Person` 与 `Planet` 进行比较) + - 宏的实现变得更加容易 + - 联合与交叉提供了一种灵活的方式以建模类型 + - 特质参数取代并简化了早期初始化器 + - [不透明类型别名][opaque_types]取代了值类的大多数用途,并确保不进行装箱 + - 导出子句提供了一种简单而通用的方式来表现聚合,它可以取代之前继承自类的包对象的外观模式 + - 删除了过程语法并更改了可变参数语法,这增加了语言一致性 + - `@infix` 注解使得您想让一个方法被如何应用更加显而易见 + - [`@targetName`]({{ site.scala3ref }}/other-new-features/targetName.html) 方法注解为方法定义了一个候补名称。这提高了与 Java 的互操作性,并允许您为符号运算符提供别名 + +在这里演示所有这些特性会占用太多空间,请通过上述内容中的链接来查看这些特性的实际效果。 +所有这些特性都在[概述文档][reference]的*新特性*、*变更的特性*、与*删除的特性*等页面中进行了详细讨论。 + +{% comment %} +CHECKLIST OF ALL ADDED, UPDATED, AND REMOVED FEATURES +===================================================== + +New Features +------------ +- trait parameters +- super traits +- creator applications +- export clauses +- opaque type aliases +- open classes +- parameter untupling +- kind polymorphism +- tupled function +- threadUnsafe annotation +- new control syntax +- optional braces (experimental) +- explicit nulls +- safe initialization + +CHANGED FEATURES +---------------- +- numeric literals +- structural types +- operators +- wildcard types +- type checking +- type inference +- implicit resolution +- implicit conversions +- overload resolution +- match expressions +- vararg patterns +- pattern bindings +- pattern matching +- eta expansion +- compiler plugins +- lazy vals initialization +- main functions + +DROPPED FEATURES +---------------- +- DelayedInit +- macros +- existential types +- type projection +- do/while syntax +- procedure syntax +- package objects +- early initializers +- class shadowing +- limit 22 +- XML literals +- symbol literals +- auto-application +- weak conformance +- nonlocal returns +- [this] qualifier + - private[this] and protected[this] access modifiers are deprecated + and will be phased out +{% endcomment %} + + +{% comment %} + +## Scala ecosystem + +{% endcomment %} + +## Scala 生态系统 + +{% comment %} +TODO: I didn’t put much work into this section because I don’t know if you want + to add many tools because (a) that can be seen as an endorsement and + (b) it creates a section that can need more maintenance than average + since tool popularity can wax and wane. One way to avoid the first + point is to base the lists on Github stars and activity. +{% endcomment %} + +{% comment %} +Scala has a vibrant ecosystem, with libraries and frameworks for every need. +The [“Awesome Scala” list](https://github.com/lauris/awesome-scala) provides a list of hundreds of open source projects that are available to Scala developers, and the [Scaladex](https://index.scala-lang.org) provides a searchable index of Scala libraries. +Some of the more notable libraries are listed below. +{% endcomment %} + +Scala 拥有一个充满活力的生态系统,有满足各种需求的库和框架。 +[Awesome Scala 列表](https://github.com/lauris/awesome-scala)提供了数百个可供 Scala 开发者使用的开源项目,[Scaladex](https://index.scala-lang.org) 则提供了 Scala 库的可搜索索引。 +以下列出了一些比较著名的库: + +{% comment %} + +### Web development + +{% endcomment %} + +### Web 开发 + +{% comment %} + +- The [Play Framework](https://www.playframework.com) followed the Ruby on Rails model to become a lightweight, stateless, developer-friendly, web-friendly architecture for highly-scalable applications +- [Scalatra](https://scalatra.org) is a tiny, high-performance, async web framework, inspired by Sinatra +- [Finatra](https://twitter.github.io/finatra) is Scala services built on TwitterServer and Finagle +- [Scala.js](https://www.scala-js.org) is a strongly-typed replacement for JavaScript that provides a safer way to build robust front-end web applications +- [ScalaJs-React](https://github.com/japgolly/scalajs-react) lifts Facebook’s React library into Scala.js, and endeavours to make it as type-safe and Scala-friendly as possible +- [Lagom](https://www.lagomframework.com) is a microservices framework that helps you decompose your legacy monolith and build, test, and deploy entire systems of Reactive microservices +- +{% endcomment %} + +- [Play Framework](https://www.playframework.com) 遵循 Ruby on Rails 模型,是一种用于高度可扩展应用程序的轻量级、无状态、对开发者及Web友好的架构 +- [Scalatra](https://scalatra.org) 是一个小型的、高性能的、异步的网络框架,其灵感来自于 Sinatra +- [Finatra](https://twitter.github.io/finatra) 是基于 TwitterServer 和 Finagle 构建的 Scala 服务 +- [Scala.js](https://www.scala-js.org) 是 JavaScript 的强类型替代品,它提供了一种更安全的方式以构建稳健的前端 Web 应用程序 +- [ScalaJs-React](https://github.com/japgolly/scalajs-react) 将 Facebook 的 React 库整合至 Scala.js,并努力使其尽可能类型安全和 Scala 友好 +- [Lagom](https://www.lagomframework.com) 是一种微服务框架,可帮助您分解遗留的单体应用并构建、测试和部署整个响应式微服务系统 + +{% comment %} +HTTP(S) libraries: +{% endcomment %} + +HTTP(S) 库: + +- [Akka-http](https://akka.io) +- [Finch](https://github.com/finagle/finch) +- [Http4s](https://github.com/http4s/http4s) +- [Sttp](https://github.com/softwaremill/sttp) + +{% comment %} +JSON libraries: +{% endcomment %} + +JSON 库: + +- [Argonaut](https://github.com/argonaut-io/argonaut) +- [Circe](https://github.com/circe/circe) +- [Json4s](https://github.com/json4s/json4s) +- [Play-JSON](https://github.com/playframework/play-json) + +{% comment %} +Serialization: +{% endcomment %} + +序列化: + +- [ScalaPB](https://github.com/scalapb/ScalaPB) + +{% comment %} + +### Science and data analysis: + +{% endcomment %} + +### 科学和数据分析 + +- [Algebird](https://github.com/twitter/algebird) +- [Spire](https://github.com/typelevel/spire) +- [Squants](https://github.com/typelevel/squants) + +{% comment %} + +### Big data + +{% endcomment %} + +### 大数据 + +- [Apache Spark](https://github.com/apache/spark) +- [Apache Flink](https://github.com/apache/flink) + +{% comment %} + +### AI, machine learning + +- [BigDL](https://github.com/intel-analytics/BigDL) (Distributed Deep Learning Framework for Apache Spark) for Apache Spark +- [TensorFlow Scala](https://github.com/eaplatanios/tensorflow_scala) + +{% endcomment %} + +### 人工智能,机器学习 + +- [BigDL](https://github.com/intel-analytics/BigDL) (用于 Apache Spark 的分布式深度学习框架) +- [TensorFlow Scala](https://github.com/eaplatanios/tensorflow_scala) + +{% comment %} + +### Functional Programming & Functional Reactive Programming + +{% endcomment %} + +### 函数式编程 & 函数式响应式编程 + +{% comment %} +FP: +{% endcomment %} + +函数式编程: + +- [Cats](https://github.com/typelevel/cats) +- [Zio](https://github.com/zio/zio) + +{% comment %} +Functional reactive programming (FRP): +{% endcomment %} + +函数式响应式编程(FRP) + +- [fs2](https://github.com/typelevel/fs2) +- [monix](https://github.com/monix/monix) + +{% comment %} + +### Build tools + +{% endcomment %} + +### 构建工具 + +- [sbt](https://www.scala-sbt.org) +- [Gradle](https://gradle.org) +- [Mill](https://github.com/lihaoyi/mill) + +{% comment %} + +## Summary + +As this page shows, Scala has many terrific programming language features at a high level, at an everyday programming level, and through its developer ecosystem. + +{% endcomment %} + +## 总结 + +如此页所示,Scala 在高层、日常编程层面以及贯穿开发者生态系统都具有许多出色的编程语言特性。 + + +[reference]: {{ site.scala3ref }}/overview.html +[multiversal]: {% link _overviews/scala3-book/ca-multiversal-equality.md %} +[extension]: {% link _overviews/scala3-book/ca-extension-methods.md %} +[givens]: {% link _overviews/scala3-book/ca-given-using-clauses.md %} +[opaque_types]: {% link _overviews/scala3-book/types-opaque-types.md %} + + + From 0eae0a35185c354be03ab5b707b993c06c555be0 Mon Sep 17 00:00:00 2001 From: Thanh Le Date: Tue, 8 Mar 2022 20:37:57 +0100 Subject: [PATCH 1792/3075] Fix link to for type lambdas url --- _overviews/scala3-migration/plugin-kind-projector.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-migration/plugin-kind-projector.md b/_overviews/scala3-migration/plugin-kind-projector.md index 6d49be8d28..8557cdb559 100644 --- a/_overviews/scala3-migration/plugin-kind-projector.md +++ b/_overviews/scala3-migration/plugin-kind-projector.md @@ -100,7 +100,7 @@ type MyLambda[F[_], A] = EitherT[F, Int, A] MyLambda ``` -Alternatively you may use Scala 3's [Native Type Lambdas](https://dotty.epfl.ch/docs/reference/new-types/type-lambdas.html) if you do not need to cross-compile: +Alternatively you may use Scala 3's [Native Type Lambdas](https://docs.scala-lang.org/scala3/reference/new-types/type-lambdas.html) if you do not need to cross-compile: ```scala [F[_], A] =>> EitherT[F, Int, A] From 9097144e071d4290dc165aee2e2855c48aae64dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Zyba=C5=82a?= Date: Tue, 8 Feb 2022 15:13:34 +0100 Subject: [PATCH 1793/3075] Update static site docs --- _overviews/scala3-scaladoc/blog.md | 13 +- _overviews/scala3-scaladoc/static-site.md | 170 ++++++++++++---------- 2 files changed, 96 insertions(+), 87 deletions(-) diff --git a/_overviews/scala3-scaladoc/blog.md b/_overviews/scala3-scaladoc/blog.md index 1e3c371c8e..612ee5c25e 100644 --- a/_overviews/scala3-scaladoc/blog.md +++ b/_overviews/scala3-scaladoc/blog.md @@ -15,24 +15,17 @@ Blog is treated a little differently than regular static sites. This article wil ## Proper directory setup -All your blogposts must be put under `blog/_posts` directory. +All your blogposts must be put under `_blog/_posts` directory. ``` -├── blog +├── _blog │ ├── _posts │ │ └── 2016-12-05-implicit-function-types.md │ └── index.html ``` -If you are using yaml [sidebar]({% link _overviews/scala3-scaladoc/static-site.md %}#sidebar) don't forget to place - -``` -sidebar: - - title: Blog -``` - -somewhere inside the `yaml` tree representing the sidebar sections. Scaladoc will attach under that section all of your blogposts. +Scaladoc loads blog if the `_blog` directory exists. ## Naming convention diff --git a/_overviews/scala3-scaladoc/static-site.md b/_overviews/scala3-scaladoc/static-site.md index e7516ea09c..d9d11f6bf6 100644 --- a/_overviews/scala3-scaladoc/static-site.md +++ b/_overviews/scala3-scaladoc/static-site.md @@ -20,16 +20,18 @@ and will from here on be referred to as "template files" or "templates". A simple "hello world" site could look something like this: ``` -├── docs -│ └── getting-started.md -└── index.html +. +└── / + └── _docs/ + ├── index.html + └── getting-started.html ``` This will give you a site with the following files in generated documentation: ``` index.html -docs/getting-started.html +getting-started.html ``` Scaladoc can transform both files and directories (to organize your documentation into a tree-like structure). By default, directories have a title based on the file name and have empty content. It is possible to provide index pages for each section by creating `index.html` or `index.md` (not both) in the dedicated directory. @@ -98,63 +100,64 @@ Layouts must be placed in a `_layouts` directory in the site root: ``` ├── _layouts │ └── main.html -├── docs -│ └── getting-started.md -└── index.html +└── _docs + └── getting-started.md +``` + +## Assets + +In order to render assets along with static site, they need to be placed in the `_assets` directory in the site root: +``` +├── _assets +│ └── images +│ └── myimage.png +└── _docs + └── getting-started.md +``` +To reference the asset in a page, one need to create link relative to the `_assets` directory + +``` +Take a look at the following image: [My image](images/myimage.png) ``` ## Sidebar -Scaladoc by default uses layout of files in `docs` directory to create table of content. There is also ability to override it by providing a `sidebar.yml` file in the site root: +Scaladoc by default uses directory structure in `_docs` directory to organize static sites. There is also possibility to override it by providing a `sidebar.yml` file in the site root. The YAML configuration file describes the structure of rendered static site and the table of content: ```yaml -sidebar: - - title: Blog - - title: My title - page: my-page1.md - - page: my-page2.md - - page: my-page3/subsection - - title: Reference - subsection: - - page: my-page3.md - - index: my-page4/index.md - subsection: - - page: my-page4/my-page4.md - - title: My subsection - index: my-page5/index.md - subsection: - - page: my-page5/my-page5.md - - index: my-page6/index.md - subsection: - - index: my-page6/my-page6/index.md - subsection: - - page: my-page6/my-page6/my-page6.md -``` - -The `sidebar` key is mandatory. -On each level, you can have three different types of entries: `page`, `blog` or `subsection`. - -`page` is a leaf of the structure and accepts the following attributes: -- `title` (optional) - title of the page -- `page` (mandatory) - path to the file that will represent the page, it can be either html or markdown file to be rendered, there is also the possibility to pass the `directory` path. If so, the scaladoc will render the directory and all its content as if there were no `sidebar.yml` basing on its tree structure and index files. - -The `page` property `subsection` accepts nested nodes, these can be either pages or subsections, which allow you to create tree-like navigation. The attributes are: -- `title` (optional) - title of the page -- `index` (optional) - path to the file that will represent the index file of the subsection, it can be either html or markdown file to be rendered -- `subsection` (mandatory) - nested nodes, can be either pages or subsections - -In `subsection`s, you can omit `title` or `index`, however not specifying any of these properties prevents you from specifying the title of the section. - -`blog` is a special node represented by simple entry `- title: Blog` with no other attributes. All your blog posts will be automatically linked under this section. You can read more about the blog [here]({% link _overviews/scala3-scaladoc/blog.md %}). - -``` -├── blog -│ ├── _posts -│ │ └── 2016-12-05-implicit-function-types.md -│ └── index.html -├── index.html -└── sidebar.yml -``` +index: index.html +subsection: + - title: Usage + index: usage/index.html + directory: usage + subsection: + - title: Dottydoc + page: usage/dottydoc.html + hidden: false + - title: sbt-projects + page: usage/sbt-projects.html + hidden: false +``` +The root element needs to be a `subsection`. +Nesting subsections will result in a tree-like structure of navigation. + +`subsection` properties are: + - `title` - Optional string - A default title of the subsection. + Front-matter titles have higher priorities. + - `index` - Optional string - A path to index page of a subsection. + - `directory` - Optional string - A name of the directory that will contain the subsection. + By default, the directory name is the subsection name converted to kebab case. + - `subsection` - Array of `subsection` or `page`. + + Either `index` or `subsection` must be defined. The subsection defined with `index` and without `subsection` will contain pages and directories loaded recursively from directory of the index page. + +`page` properties are: + - `title` - Optional string - A default title of the page. + Front-matter titles have higher priorities. + - `page` - String - A path to the page + - `hidden` - Optional boolean - A flag that indicates whether the page should be visible in navigation. By default, it is set to `false`. + +**Note**: All paths in YAML configuration file are relative to `/_docs`. ## Hierarchy of title @@ -174,30 +177,43 @@ If the title is specified multiple times, the priority is as follows (from highe Note that if you skip the `index` file in your tree structure or you don't specify the `title` in the frontmatter, there will be given a generic name `index`. The same applies when using `sidebar.yml` but not specifying `title` nor `index`, just a subsection. Again, a generic `index` name will appear. +## Blog +Blog feature is described in [a separate document]({% link _overviews/scala3-scaladoc/blog.md %}) -## Static resources - -You can attach static resources (pdf, images) to your documentation by using two dedicated directories: -`resources` and `images`. After placing your assets under any of these directories, you can reference them in markdown -as if they were relatively at the same level. - -For example, consider the following situation: - +## Advanced configuration +### Full structure of site root ``` -├── blog -│ ├── _posts -│ │ └── 2016-12-05-implicit-function-types.md -│ └── index.html -├── index.html -├── resources -│ └── my_file.pdf -├── images -│ └── my_image.png -└── sidebar.yml - +. +└── / + ├── _layouts_/ + │ └── ... + ├── _docs/ + │ └── ... + ├── _blog/ + │ ├── index.md + │ └── _posts/ + │ └── ... + └── _assets/ + ├── js/ + │ └── ... + ├── img/ + │ └── ... + └── ... ``` +It results in static site containing documents as well as blog. It also contains custom layouts and assets. The structure of rendered documentation can be based on file system but it can also be overriden by YAML configuration. -You can refer to the assets from within any of the files using markdown links: +### Mapping directory structure -``` -This is my blog post. Here is the image ![](my_image.png) and here is my [pdf](my_file.pdf)``` +Using YAML configuration file, we can define how the source directory structure should be transformed in target directory structure. + +Take a look at following subsection definition: +```yaml +- title: Some other subsection + index: abc/index.html + directory: custom-directory + subsection: + - page: abc2/page1.md + - page: foo/page2.md +``` +This subsection shows the ability of YAML configuration to map the directory structure. +Even though the index page and all defined children are in different directories, they will be rendered in `custom-directory`. From 6e2cf92d84dc4ee4290dc65cd83f2a4a4b250796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filip=20Zyba=C5=82a?= Date: Thu, 10 Mar 2022 09:05:31 +0100 Subject: [PATCH 1794/3075] Apply suggestions from review --- _overviews/scala3-scaladoc/static-site.md | 27 +++++++++++++---------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/_overviews/scala3-scaladoc/static-site.md b/_overviews/scala3-scaladoc/static-site.md index d9d11f6bf6..127f6c59e7 100644 --- a/_overviews/scala3-scaladoc/static-site.md +++ b/_overviews/scala3-scaladoc/static-site.md @@ -101,7 +101,8 @@ Layouts must be placed in a `_layouts` directory in the site root: ├── _layouts │ └── main.html └── _docs - └── getting-started.md + ├── getting-started.md + └── index.html ``` ## Assets @@ -114,7 +115,7 @@ In order to render assets along with static site, they need to be placed in the └── _docs └── getting-started.md ``` -To reference the asset in a page, one need to create link relative to the `_assets` directory +To reference the asset on a page, one needs to create a link relative to the `_assets` directory ``` Take a look at the following image: [My image](images/myimage.png) @@ -122,7 +123,7 @@ Take a look at the following image: [My image](images/myimage.png) ## Sidebar -Scaladoc by default uses directory structure in `_docs` directory to organize static sites. There is also possibility to override it by providing a `sidebar.yml` file in the site root. The YAML configuration file describes the structure of rendered static site and the table of content: +By default, Scaladoc reflects the directory structure from `_docs` directory in the rendered site. There is also the ability to override it by providing a `sidebar.yml` file in the site root directory. The YAML configuration file describes the structure of the rendered static site and the table of content: ```yaml index: index.html @@ -144,20 +145,20 @@ Nesting subsections will result in a tree-like structure of navigation. `subsection` properties are: - `title` - Optional string - A default title of the subsection. Front-matter titles have higher priorities. - - `index` - Optional string - A path to index page of a subsection. - - `directory` - Optional string - A name of the directory that will contain the subsection. + - `index` - Optional string - A path to index page of a subsection. The path is relative to the `_docs` directory. + - `directory` - Optional string - A name of the directory that will contain the subsection in the generated site. By default, the directory name is the subsection name converted to kebab case. - `subsection` - Array of `subsection` or `page`. - Either `index` or `subsection` must be defined. The subsection defined with `index` and without `subsection` will contain pages and directories loaded recursively from directory of the index page. + Either `index` or `subsection` must be defined. The subsection defined with `index` and without `subsection` will contain pages and directories loaded recursively from the directory of the index page. `page` properties are: - `title` - Optional string - A default title of the page. Front-matter titles have higher priorities. - - `page` - String - A path to the page - - `hidden` - Optional boolean - A flag that indicates whether the page should be visible in navigation. By default, it is set to `false`. + - `page` - String - A path to the page, relative to the `_docs` directory. + - `hidden` - Optional boolean - A flag that indicates whether the page should be visible in the navigation sidebar. By default, it is set to `false`. -**Note**: All paths in YAML configuration file are relative to `/_docs`. +**Note**: All the paths in the YAML configuration file are relative to `/_docs`. ## Hierarchy of title @@ -200,13 +201,13 @@ Blog feature is described in [a separate document]({% link _overviews/scala3-sca │ └── ... └── ... ``` -It results in static site containing documents as well as blog. It also contains custom layouts and assets. The structure of rendered documentation can be based on file system but it can also be overriden by YAML configuration. +It results in a static site containing documents as well as a blog. It also contains custom layouts and assets. The structure of the rendered documentation can be based on the file system but it can also be overridden by YAML configuration. ### Mapping directory structure -Using YAML configuration file, we can define how the source directory structure should be transformed in target directory structure. +Using the YAML configuration file, we can define how the source directory structure should be transformed into an outputs directory structure. -Take a look at following subsection definition: +Take a look at the following subsection definition: ```yaml - title: Some other subsection index: abc/index.html @@ -217,3 +218,5 @@ Take a look at following subsection definition: ``` This subsection shows the ability of YAML configuration to map the directory structure. Even though the index page and all defined children are in different directories, they will be rendered in `custom-directory`. +The source page `abc/index.html` will generate a page `custom-directory/index.html`, the source page `abc2/page1.md` will generate a page `custom-directory/page1.html`, +and the source page `foo/page2.md` will generate a page `custom-directory/page2.html`. From 388973da5dfc75990bb00be1d15ea2bd217b8780 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Mon, 14 Mar 2022 14:12:50 +0100 Subject: [PATCH 1795/3075] list scala 3 releases in api/all --- api/all.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/api/all.md b/api/all.md index ddf77295f7..ea55e544d9 100644 --- a/api/all.md +++ b/api/all.md @@ -6,6 +6,8 @@ includeTOC: true ## Latest releases +* Scala 3.1.1 + * [Library API](https://www.scala-lang.org/api/3.1.1/) * Scala 2.13.8 * [Library API](https://www.scala-lang.org/api/2.13.8/) * [Compiler API](https://www.scala-lang.org/api/2.13.8/scala-compiler/scala/) @@ -58,6 +60,14 @@ https://scala-ci.typesafe.com/artifactory/scala-integration/org/scala-lang/ ## Previous releases +* Scala 3.1.0 + * [Library API](https://www.scala-lang.org/api/3.1.0/) +* Scala 3.0.2 + * [Library API](https://www.scala-lang.org/api/3.0.2/) +* Scala 3.0.1 + * [Library API](https://www.scala-lang.org/api/3.0.1/) +* Scala 3.0.0 + * [Library API](https://www.scala-lang.org/api/3.0.0/) * Scala 2.13.7 * [Library API](https://www.scala-lang.org/api/2.13.7/) * [Compiler API](https://www.scala-lang.org/api/2.13.7/scala-compiler/scala/) From 5152494a70fb70694d0381474115e404d7e89317 Mon Sep 17 00:00:00 2001 From: TSLsun Date: Sat, 19 Mar 2022 11:10:20 +0800 Subject: [PATCH 1796/3075] fix compiling warnings in code example --- _tour/classes.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_tour/classes.md b/_tour/classes.md index 47b5079bc5..ee3dc33703 100644 --- a/_tour/classes.md +++ b/_tour/classes.md @@ -76,17 +76,17 @@ class Point { private var _y = 0 private val bound = 100 - def x = _x + def x: Int = _x def x_= (newValue: Int): Unit = { - if (newValue < bound) _x = newValue else printWarning + if (newValue < bound) _x = newValue else printWarning() } - def y = _y + def y: Int = _y def y_= (newValue: Int): Unit = { - if (newValue < bound) _y = newValue else printWarning + if (newValue < bound) _y = newValue else printWarning() } - private def printWarning = println("WARNING: Out of bounds") + private def printWarning(): Unit = println("WARNING: Out of bounds") } val point1 = new Point From 532dbc3f09686cedda3ac3cf8fd90986f5ffbe85 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Mon, 21 Mar 2022 11:51:25 +0100 Subject: [PATCH 1797/3075] enable collection contribute_resources change icons in contribute_resources --- _config.yml | 1 + _contribute_resources/1-documentation.md | 2 +- _contribute_resources/2-bug-fixes.md | 2 +- _contribute_resources/6-compiler-language.md | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/_config.yml b/_config.yml index ecd8829749..0d58e58a8f 100644 --- a/_config.yml +++ b/_config.yml @@ -20,6 +20,7 @@ scala-212-version: 2.12.15 scala-3-version: 3.1.1 collections: + contribute_resources: style: output: true overviews: diff --git a/_contribute_resources/1-documentation.md b/_contribute_resources/1-documentation.md index b39290a394..431c4e0ab1 100644 --- a/_contribute_resources/1-documentation.md +++ b/_contribute_resources/1-documentation.md @@ -1,6 +1,6 @@ --- title: Documentation link: /contribute/documentation.html -icon: fa fa-file-text +icon: fa fa-book --- [Scaladoc (API)](/contribute/scala-standard-library-api-documentation.html), [docs.scala-lang.org](https://docs.scala-lang.org/contribute.html) and [scala-lang.org](https://github.com/scala/scala-lang). diff --git a/_contribute_resources/2-bug-fixes.md b/_contribute_resources/2-bug-fixes.md index cca6269e06..54e6d2cf9d 100644 --- a/_contribute_resources/2-bug-fixes.md +++ b/_contribute_resources/2-bug-fixes.md @@ -1,6 +1,6 @@ --- title: Bug fixes link: /contribute/guide.html -icon: fa fa-pencil +icon: fa fa-bug --- Issues with the tools, core libraries and compiler. Also you can help us by [reporting bugs](/contribute/bug-reporting-guide.html). diff --git a/_contribute_resources/6-compiler-language.md b/_contribute_resources/6-compiler-language.md index fcfea35d5a..d54e34fac9 100644 --- a/_contribute_resources/6-compiler-language.md +++ b/_contribute_resources/6-compiler-language.md @@ -1,6 +1,6 @@ --- title: Compiler/Language link: /contribute/guide.html#larger-changes-new-features -icon: fa fa-gears +icon: fa fa-cogs --- Larger language features and compiler enhancements including language specification and SIPs. From d9c44ebf1f469c7d8ed2b46c2a38f0940569b6e2 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Mon, 21 Mar 2022 13:13:26 +0100 Subject: [PATCH 1798/3075] prepare for move files --- contribute/bug-reporting-guide.md | 4 ++-- contribute/codereviews.md | 2 +- contribute/corelibs.md | 2 +- contribute/documentation.md | 2 +- contribute/guide.md | 2 +- contribute/hacker-guide.md | 2 +- contribute/index.md | 2 +- contribute/partest-guide.md | 4 ++-- contribute/scala-internals.md | 2 +- contribute/scala-standard-library-api-documentation.md | 2 +- contribute/tools.md | 2 +- 11 files changed, 13 insertions(+), 13 deletions(-) diff --git a/contribute/bug-reporting-guide.md b/contribute/bug-reporting-guide.md index 88317da0ce..d4588de422 100644 --- a/contribute/bug-reporting-guide.md +++ b/contribute/bug-reporting-guide.md @@ -1,8 +1,8 @@ --- -title: Bug Reporting +title: Bug Reporting Guide layout: inner-page-no-masthead -# permalink: /contribute/bug-reporting-guide/ includeTOC: true +permalink: /contribute/bug-reporting-guide.html --- The Scala compiler and standard library bug tracker is located at [https://github.com/scala/bug](https://github.com/scala/bug). Before you submit a bug make sure that it is certainly a bug by following instructions in *Is it a Bug?*. diff --git a/contribute/codereviews.md b/contribute/codereviews.md index 6e0a2592b6..860ba65884 100644 --- a/contribute/codereviews.md +++ b/contribute/codereviews.md @@ -1,8 +1,8 @@ --- title: Code Review Contributions layout: inner-page-no-masthead -# permalink: /contribute/codereviews/ includeTOC: true +permalink: /contribute/codereviews.html --- ## Code Review Contributions diff --git a/contribute/corelibs.md b/contribute/corelibs.md index 6b2cc5d95f..4f10208334 100644 --- a/contribute/corelibs.md +++ b/contribute/corelibs.md @@ -1,8 +1,8 @@ --- title: Core Library Contributions layout: inner-page-no-masthead -# permalink: /contribute/corelibs/ includeTOC: true +permalink: /contribute/corelibs.html --- ## Core Library Contributions diff --git a/contribute/documentation.md b/contribute/documentation.md index 967806de42..b8ea229f93 100644 --- a/contribute/documentation.md +++ b/contribute/documentation.md @@ -1,8 +1,8 @@ --- title: Documentation Contributions layout: inner-page-no-masthead -# permalink: /contribute/documentation/ includeTOC: true +permalink: /contribute/documentation.html --- ## Contributing Documentation to the Scala project diff --git a/contribute/guide.md b/contribute/guide.md index 7e4f375005..c10a5c20c1 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -1,8 +1,8 @@ --- title: Contributing guide layout: inner-page-no-masthead -# permalink: /contribute/guide/ includeTOC: true +permalink: /contribute/guide.html ---
diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 302635fae1..990754e3df 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -2,8 +2,8 @@ title: Scala hacker guide by: Eugene Burmako layout: inner-page-no-masthead -# permalink: /contribute/hacker-guide/ includeTOC: true +permalink: /contribute/hacker-guide.html ---
This guide is intended to help you get from an idea of fixing a bug or implementing a new feature into a nightly Scala build, and, ultimately, to a production release of Scala incorporating your idea. diff --git a/contribute/index.md b/contribute/index.md index d78a72e159..d4bc7069a2 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -1,8 +1,8 @@ --- title: Contribute layout: inner-page-no-masthead -# permalink: /contribute/ includeTOC: true +permalink: /contribute/ --- The Scala programming language is an open source project with a very diff --git a/contribute/partest-guide.md b/contribute/partest-guide.md index e7e10621e1..d55c02e884 100644 --- a/contribute/partest-guide.md +++ b/contribute/partest-guide.md @@ -1,8 +1,8 @@ --- title: Running the Test Suite layout: inner-page-no-masthead -# permalink: /contribute/partest-guide/ includeTOC: true +permalink: /contribute/partest-guide.html --- Partest is a custom parallel testing tool that we use to run the test suite for the Scala compiler and library. Go to the scala project folder from your local checkout and run it via `sbt`, `ant` or standalone as follows. @@ -35,7 +35,7 @@ The test suite can be run by using ant from the command line: Please note the standalone scripts mentioned below were removed in 2.12.2. sbt is the preferred way to run the test suite. -There are launch scripts `partest` and `partest.bat` in the `test` folder of the scala project. To have partest run failing tests only and print details about test failures to the console, you can use +There are launch scripts `partest` and `partest.bat` in the `test` folder of the scala project. To have partest run failing tests only and print details about test failures to the console, you can use ./test/partest --show-diff --show-log --failed diff --git a/contribute/scala-internals.md b/contribute/scala-internals.md index e6fde53a81..b380525088 100644 --- a/contribute/scala-internals.md +++ b/contribute/scala-internals.md @@ -1,8 +1,8 @@ --- title: Scala Internals Mailing List layout: inner-page-no-masthead -permalink: /contribute/scala-internals/ includeTOC: true +permalink: /contribute/scala-internals/ --- ## scala-internals diff --git a/contribute/scala-standard-library-api-documentation.md b/contribute/scala-standard-library-api-documentation.md index 6f3af62b30..2700d2fd11 100644 --- a/contribute/scala-standard-library-api-documentation.md +++ b/contribute/scala-standard-library-api-documentation.md @@ -1,8 +1,8 @@ --- title: Contribute to API Documentation layout: inner-page-no-masthead -# permalink: /contribute/scala-standard-library-api-documentation.html includeTOC: true +permalink: /contribute/scala-standard-library-api-documentation.html --- This page is specific to API documentation contributions – that is, API diff --git a/contribute/tools.md b/contribute/tools.md index 0afd3982d8..a76d0b90bd 100644 --- a/contribute/tools.md +++ b/contribute/tools.md @@ -1,8 +1,8 @@ --- title: IDE and Build Tool Contributions layout: inner-page-no-masthead -# permalink: /contribute/tools/ includeTOC: true +permalink: /contribute/tools.html # Projects list: projects: From 30735654a67e967f41a9c7162b64846f2050f5ae Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Mon, 21 Mar 2022 13:14:45 +0100 Subject: [PATCH 1799/3075] move contribute files --- {contribute => _overviews/contribute}/bug-reporting-guide.md | 0 {contribute => _overviews/contribute}/codereviews.md | 0 {contribute => _overviews/contribute}/corelibs.md | 0 {contribute => _overviews/contribute}/documentation.md | 0 {contribute => _overviews/contribute}/guide.md | 0 {contribute => _overviews/contribute}/hacker-guide.md | 0 {contribute => _overviews/contribute}/inclusive-language-guide.md | 0 {contribute => _overviews/contribute}/index.md | 0 {contribute => _overviews/contribute}/partest-guide.md | 0 {contribute => _overviews/contribute}/scala-internals.md | 0 .../contribute}/scala-standard-library-api-documentation.md | 0 {contribute => _overviews/contribute}/tools.md | 0 12 files changed, 0 insertions(+), 0 deletions(-) rename {contribute => _overviews/contribute}/bug-reporting-guide.md (100%) rename {contribute => _overviews/contribute}/codereviews.md (100%) rename {contribute => _overviews/contribute}/corelibs.md (100%) rename {contribute => _overviews/contribute}/documentation.md (100%) rename {contribute => _overviews/contribute}/guide.md (100%) rename {contribute => _overviews/contribute}/hacker-guide.md (100%) rename {contribute => _overviews/contribute}/inclusive-language-guide.md (100%) rename {contribute => _overviews/contribute}/index.md (100%) rename {contribute => _overviews/contribute}/partest-guide.md (100%) rename {contribute => _overviews/contribute}/scala-internals.md (100%) rename {contribute => _overviews/contribute}/scala-standard-library-api-documentation.md (100%) rename {contribute => _overviews/contribute}/tools.md (100%) diff --git a/contribute/bug-reporting-guide.md b/_overviews/contribute/bug-reporting-guide.md similarity index 100% rename from contribute/bug-reporting-guide.md rename to _overviews/contribute/bug-reporting-guide.md diff --git a/contribute/codereviews.md b/_overviews/contribute/codereviews.md similarity index 100% rename from contribute/codereviews.md rename to _overviews/contribute/codereviews.md diff --git a/contribute/corelibs.md b/_overviews/contribute/corelibs.md similarity index 100% rename from contribute/corelibs.md rename to _overviews/contribute/corelibs.md diff --git a/contribute/documentation.md b/_overviews/contribute/documentation.md similarity index 100% rename from contribute/documentation.md rename to _overviews/contribute/documentation.md diff --git a/contribute/guide.md b/_overviews/contribute/guide.md similarity index 100% rename from contribute/guide.md rename to _overviews/contribute/guide.md diff --git a/contribute/hacker-guide.md b/_overviews/contribute/hacker-guide.md similarity index 100% rename from contribute/hacker-guide.md rename to _overviews/contribute/hacker-guide.md diff --git a/contribute/inclusive-language-guide.md b/_overviews/contribute/inclusive-language-guide.md similarity index 100% rename from contribute/inclusive-language-guide.md rename to _overviews/contribute/inclusive-language-guide.md diff --git a/contribute/index.md b/_overviews/contribute/index.md similarity index 100% rename from contribute/index.md rename to _overviews/contribute/index.md diff --git a/contribute/partest-guide.md b/_overviews/contribute/partest-guide.md similarity index 100% rename from contribute/partest-guide.md rename to _overviews/contribute/partest-guide.md diff --git a/contribute/scala-internals.md b/_overviews/contribute/scala-internals.md similarity index 100% rename from contribute/scala-internals.md rename to _overviews/contribute/scala-internals.md diff --git a/contribute/scala-standard-library-api-documentation.md b/_overviews/contribute/scala-standard-library-api-documentation.md similarity index 100% rename from contribute/scala-standard-library-api-documentation.md rename to _overviews/contribute/scala-standard-library-api-documentation.md diff --git a/contribute/tools.md b/_overviews/contribute/tools.md similarity index 100% rename from contribute/tools.md rename to _overviews/contribute/tools.md From db3d07ea0ff961fd5000fe4adf99491b6a01645e Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Mon, 21 Mar 2022 13:27:32 +0100 Subject: [PATCH 1800/3075] convert to multipage overview --- _overviews/contribute/bug-reporting-guide.md | 6 ++++-- _overviews/contribute/codereviews.md | 6 ++++-- _overviews/contribute/corelibs.md | 6 ++++-- _overviews/contribute/documentation.md | 6 ++++-- _overviews/contribute/guide.md | 6 ++++-- _overviews/contribute/hacker-guide.md | 6 ++++-- _overviews/contribute/inclusive-language-guide.md | 6 ++++-- _overviews/contribute/index.md | 6 ++++-- _overviews/contribute/partest-guide.md | 6 ++++-- _overviews/contribute/scala-internals.md | 6 ++++-- .../contribute/scala-standard-library-api-documentation.md | 6 ++++-- _overviews/contribute/tools.md | 6 ++++-- 12 files changed, 48 insertions(+), 24 deletions(-) diff --git a/_overviews/contribute/bug-reporting-guide.md b/_overviews/contribute/bug-reporting-guide.md index d4588de422..3e358a30f0 100644 --- a/_overviews/contribute/bug-reporting-guide.md +++ b/_overviews/contribute/bug-reporting-guide.md @@ -1,7 +1,9 @@ --- title: Bug Reporting Guide -layout: inner-page-no-masthead -includeTOC: true +layout: multipage-overview +num: 7 +partof: scala-contribution +overview-name: Contributing to Scala permalink: /contribute/bug-reporting-guide.html --- diff --git a/_overviews/contribute/codereviews.md b/_overviews/contribute/codereviews.md index 860ba65884..5b5a4a4697 100644 --- a/_overviews/contribute/codereviews.md +++ b/_overviews/contribute/codereviews.md @@ -1,7 +1,9 @@ --- title: Code Review Contributions -layout: inner-page-no-masthead -includeTOC: true +layout: multipage-overview +num: 3 +partof: scala-contribution +overview-name: Contributing to Scala permalink: /contribute/codereviews.html --- ## Code Review Contributions diff --git a/_overviews/contribute/corelibs.md b/_overviews/contribute/corelibs.md index 4f10208334..984f8c4f7c 100644 --- a/_overviews/contribute/corelibs.md +++ b/_overviews/contribute/corelibs.md @@ -1,7 +1,9 @@ --- title: Core Library Contributions -layout: inner-page-no-masthead -includeTOC: true +layout: multipage-overview +num: 4 +partof: scala-contribution +overview-name: Contributing to Scala permalink: /contribute/corelibs.html --- ## Core Library Contributions diff --git a/_overviews/contribute/documentation.md b/_overviews/contribute/documentation.md index b8ea229f93..01cd8a5c15 100644 --- a/_overviews/contribute/documentation.md +++ b/_overviews/contribute/documentation.md @@ -1,7 +1,9 @@ --- title: Documentation Contributions -layout: inner-page-no-masthead -includeTOC: true +layout: multipage-overview +num: 5 +partof: scala-contribution +overview-name: Contributing to Scala permalink: /contribute/documentation.html --- ## Contributing Documentation to the Scala project diff --git a/_overviews/contribute/guide.md b/_overviews/contribute/guide.md index c10a5c20c1..7cafd3d8a3 100644 --- a/_overviews/contribute/guide.md +++ b/_overviews/contribute/guide.md @@ -1,7 +1,9 @@ --- title: Contributing guide -layout: inner-page-no-masthead -includeTOC: true +layout: multipage-overview +num: 9 +partof: scala-contribution +overview-name: Contributing to Scala permalink: /contribute/guide.html --- diff --git a/_overviews/contribute/hacker-guide.md b/_overviews/contribute/hacker-guide.md index 990754e3df..df659678cb 100644 --- a/_overviews/contribute/hacker-guide.md +++ b/_overviews/contribute/hacker-guide.md @@ -1,8 +1,10 @@ --- title: Scala hacker guide by: Eugene Burmako -layout: inner-page-no-masthead -includeTOC: true +layout: multipage-overview +num: 11 +partof: scala-contribution +overview-name: Contributing to Scala permalink: /contribute/hacker-guide.html ---
diff --git a/_overviews/contribute/inclusive-language-guide.md b/_overviews/contribute/inclusive-language-guide.md index 6703532594..d673d57ad8 100644 --- a/_overviews/contribute/inclusive-language-guide.md +++ b/_overviews/contribute/inclusive-language-guide.md @@ -1,7 +1,9 @@ --- title: Inclusive Language Guide -layout: inner-page-no-masthead -includeTOC: true +layout: multipage-overview +num: 2 +partof: scala-contribution +overview-name: Contributing to Scala permalink: /contribute/inclusive-language/ --- diff --git a/_overviews/contribute/index.md b/_overviews/contribute/index.md index d4bc7069a2..ac513b0009 100644 --- a/_overviews/contribute/index.md +++ b/_overviews/contribute/index.md @@ -1,7 +1,9 @@ --- title: Contribute -layout: inner-page-no-masthead -includeTOC: true +layout: multipage-overview +num: 1 +partof: scala-contribution +overview-name: Contributing to Scala permalink: /contribute/ --- diff --git a/_overviews/contribute/partest-guide.md b/_overviews/contribute/partest-guide.md index d55c02e884..8f4dff394b 100644 --- a/_overviews/contribute/partest-guide.md +++ b/_overviews/contribute/partest-guide.md @@ -1,7 +1,9 @@ --- title: Running the Test Suite -layout: inner-page-no-masthead -includeTOC: true +layout: multipage-overview +num: 12 +partof: scala-contribution +overview-name: Contributing to Scala permalink: /contribute/partest-guide.html --- diff --git a/_overviews/contribute/scala-internals.md b/_overviews/contribute/scala-internals.md index b380525088..f52faa5c18 100644 --- a/_overviews/contribute/scala-internals.md +++ b/_overviews/contribute/scala-internals.md @@ -1,7 +1,9 @@ --- title: Scala Internals Mailing List -layout: inner-page-no-masthead -includeTOC: true +layout: multipage-overview +num: 8 +partof: scala-contribution +overview-name: Contributing to Scala permalink: /contribute/scala-internals/ --- diff --git a/_overviews/contribute/scala-standard-library-api-documentation.md b/_overviews/contribute/scala-standard-library-api-documentation.md index 2700d2fd11..97e3d708f9 100644 --- a/_overviews/contribute/scala-standard-library-api-documentation.md +++ b/_overviews/contribute/scala-standard-library-api-documentation.md @@ -1,7 +1,9 @@ --- title: Contribute to API Documentation -layout: inner-page-no-masthead -includeTOC: true +layout: multipage-overview +num: 6 +partof: scala-contribution +overview-name: Contributing to Scala permalink: /contribute/scala-standard-library-api-documentation.html --- diff --git a/_overviews/contribute/tools.md b/_overviews/contribute/tools.md index a76d0b90bd..6df7c454a9 100644 --- a/_overviews/contribute/tools.md +++ b/_overviews/contribute/tools.md @@ -1,7 +1,9 @@ --- title: IDE and Build Tool Contributions -layout: inner-page-no-masthead -includeTOC: true +layout: multipage-overview +num: 10 +partof: scala-contribution +overview-name: Contributing to Scala permalink: /contribute/tools.html # Projects list: From c692ad3ab96c94ea22c9f5e99e0cabcccd76489b Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Mon, 21 Mar 2022 13:59:30 +0100 Subject: [PATCH 1801/3075] migrate urls to /overviews/contribute fix broken links --- _contribute_resources/1-documentation.md | 4 +-- _contribute_resources/2-bug-fixes.md | 4 +-- _contribute_resources/3-code-reviews.md | 6 ++-- _contribute_resources/4-core-libraries.md | 2 +- .../5-ide-and-build-tools.md | 2 +- _contribute_resources/6-compiler-language.md | 2 +- _overviews/contribute/bug-reporting-guide.md | 1 - _overviews/contribute/codereviews.md | 7 ++-- _overviews/contribute/corelibs.md | 7 ++-- _overviews/contribute/documentation.md | 11 +++---- _overviews/contribute/guide.md | 33 +++++++++---------- _overviews/contribute/hacker-guide.md | 11 +++---- .../contribute/inclusive-language-guide.md | 3 +- _overviews/contribute/index.md | 9 +++-- _overviews/contribute/partest-guide.md | 1 - _overviews/contribute/scala-internals.md | 1 - ...cala-standard-library-api-documentation.md | 7 ++-- _overviews/contribute/tools.md | 7 ++-- 18 files changed, 53 insertions(+), 65 deletions(-) diff --git a/_contribute_resources/1-documentation.md b/_contribute_resources/1-documentation.md index 431c4e0ab1..3e1b81a7b9 100644 --- a/_contribute_resources/1-documentation.md +++ b/_contribute_resources/1-documentation.md @@ -1,6 +1,6 @@ --- title: Documentation -link: /contribute/documentation.html +link: /overviews/contribute/documentation.html icon: fa fa-book --- -[Scaladoc (API)](/contribute/scala-standard-library-api-documentation.html), [docs.scala-lang.org](https://docs.scala-lang.org/contribute.html) and [scala-lang.org](https://github.com/scala/scala-lang). +[Scaladoc (API)](/overviews/contribute/scala-standard-library-api-documentation.html), [docs.scala-lang.org](/contribute.html) and [scala-lang.org](https://github.com/scala/scala-lang). diff --git a/_contribute_resources/2-bug-fixes.md b/_contribute_resources/2-bug-fixes.md index 54e6d2cf9d..2baf672e5a 100644 --- a/_contribute_resources/2-bug-fixes.md +++ b/_contribute_resources/2-bug-fixes.md @@ -1,6 +1,6 @@ --- title: Bug fixes -link: /contribute/guide.html +link: /overviews/contribute/guide.html icon: fa fa-bug --- -Issues with the tools, core libraries and compiler. Also you can help us by [reporting bugs](/contribute/bug-reporting-guide.html). +Issues with the tools, core libraries and compiler. Also you can help us by [reporting bugs](/overviews/contribute/bug-reporting-guide.html). diff --git a/_contribute_resources/3-code-reviews.md b/_contribute_resources/3-code-reviews.md index 2fc057eb0d..41f6821414 100644 --- a/_contribute_resources/3-code-reviews.md +++ b/_contribute_resources/3-code-reviews.md @@ -1,8 +1,8 @@ --- title: Code Reviews -link: /contribute/codereviews.html +link: /overviews/contribute/codereviews.html icon: fa fa-eye --- -Review pull requests against [scala/scala](https://github.com/scala/scala/pulls), -[scala/scala-lang](https://github.com/scala/scala-lang/pulls), +Review pull requests against [scala/scala](https://github.com/scala/scala/pulls), +[scala/scala-lang](https://github.com/scala/scala-lang/pulls), [scala/docs.scala-lang](https://github.com/scala/docs.scala-lang/pulls) and others. diff --git a/_contribute_resources/4-core-libraries.md b/_contribute_resources/4-core-libraries.md index 06f1018479..fb66a906b8 100644 --- a/_contribute_resources/4-core-libraries.md +++ b/_contribute_resources/4-core-libraries.md @@ -1,6 +1,6 @@ --- title: Core Libraries -link: /contribute/corelibs.html +link: /overviews/contribute/corelibs.html icon: fa fa-clipboard --- Update and expand the capabilities of the core (and associated) Scala libraries. diff --git a/_contribute_resources/5-ide-and-build-tools.md b/_contribute_resources/5-ide-and-build-tools.md index 7202f0d953..2bf2c7d729 100644 --- a/_contribute_resources/5-ide-and-build-tools.md +++ b/_contribute_resources/5-ide-and-build-tools.md @@ -1,6 +1,6 @@ --- title: IDE and Build Tools -link: /contribute/tools.html +link: /overviews/contribute/tools.html icon: fa fa-terminal --- Enhance the Scala tools with features for build tools, IDE plug-ins and other related projects. diff --git a/_contribute_resources/6-compiler-language.md b/_contribute_resources/6-compiler-language.md index d54e34fac9..a7dc618322 100644 --- a/_contribute_resources/6-compiler-language.md +++ b/_contribute_resources/6-compiler-language.md @@ -1,6 +1,6 @@ --- title: Compiler/Language -link: /contribute/guide.html#larger-changes-new-features +link: /overviews/contribute/guide.html#larger-changes-new-features icon: fa fa-cogs --- Larger language features and compiler enhancements including language specification and SIPs. diff --git a/_overviews/contribute/bug-reporting-guide.md b/_overviews/contribute/bug-reporting-guide.md index 3e358a30f0..5cbf0a3f46 100644 --- a/_overviews/contribute/bug-reporting-guide.md +++ b/_overviews/contribute/bug-reporting-guide.md @@ -4,7 +4,6 @@ layout: multipage-overview num: 7 partof: scala-contribution overview-name: Contributing to Scala -permalink: /contribute/bug-reporting-guide.html --- The Scala compiler and standard library bug tracker is located at [https://github.com/scala/bug](https://github.com/scala/bug). Before you submit a bug make sure that it is certainly a bug by following instructions in *Is it a Bug?*. diff --git a/_overviews/contribute/codereviews.md b/_overviews/contribute/codereviews.md index 5b5a4a4697..368bf96793 100644 --- a/_overviews/contribute/codereviews.md +++ b/_overviews/contribute/codereviews.md @@ -4,11 +4,10 @@ layout: multipage-overview num: 3 partof: scala-contribution overview-name: Contributing to Scala -permalink: /contribute/codereviews.html --- ## Code Review Contributions -In addition to [bug fixing](/contribute/guide.html), you can help us review +In addition to [bug fixing](/overviews/contribute/guide.html), you can help us review [waiting pull requests](#pull-requests-awaiting-comment). This is also a good (and recommended) way to get to know the feel of the bug-fixing and submissions process before jumping in with your @@ -17,7 +16,7 @@ own pull requests. ### Review Guidelines -[Code of Conduct reminder]({{ site.baseurl }}/conduct.html) +[Code of Conduct reminder](https://scala-lang.org/conduct.html) * Keep comments on-topic, concise and precise. * Attach comments to particular lines or regions they pertain to whenever possible. @@ -53,4 +52,4 @@ own pull requests.
-Also note that the [Tools contributions](/contribute/tools.html) page has more projects that will generate pull requests. +Also note that the [Tools contributions](/overviews/contribute/tools.html) page has more projects that will generate pull requests. diff --git a/_overviews/contribute/corelibs.md b/_overviews/contribute/corelibs.md index 984f8c4f7c..6c64a887d7 100644 --- a/_overviews/contribute/corelibs.md +++ b/_overviews/contribute/corelibs.md @@ -4,15 +4,14 @@ layout: multipage-overview num: 4 partof: scala-contribution overview-name: Contributing to Scala -permalink: /contribute/corelibs.html --- ## Core Library Contributions There are several options for contributing to Scala's core libraries. You can: -* Help with [Documentation](/contribute/documentation.html). -* [Report Bugs or Issues](/contribute/bug-reporting-guide.html) against the core libraries. -* [Fix Bugs or Issues](/contribute/guide.html) against the +* Help with [Documentation](/overviews/contribute/documentation.html). +* [Report Bugs or Issues](/overviews/contribute/bug-reporting-guide.html) against the core libraries. +* [Fix Bugs or Issues](/overviews/contribute/guide.html) against the [reported library bugs/issues](https://github.com/scala/bug). ### Significant changes diff --git a/_overviews/contribute/documentation.md b/_overviews/contribute/documentation.md index 01cd8a5c15..7fca82ff53 100644 --- a/_overviews/contribute/documentation.md +++ b/_overviews/contribute/documentation.md @@ -4,7 +4,6 @@ layout: multipage-overview num: 5 partof: scala-contribution overview-name: Contributing to Scala -permalink: /contribute/documentation.html --- ## Contributing Documentation to the Scala project @@ -24,11 +23,11 @@ Thanks The Scala API documentation lives with the scala project source code. There are many ways you can help with improving Scaladoc, including: -* [Log issues for missing scaladoc documentation](/contribute/scala-standard-library-api-documentation.html#contribute-api-documentation-bug-reports) - +* [Log issues for missing scaladoc documentation](/overviews/contribute/scala-standard-library-api-documentation.html#contribute-api-documentation-bug-reports) - Please *follow the issue submission process closely* to help prevent duplicate issues being created. -* [Claim Scaladoc Issues and Provide Documentation](/contribute/scala-standard-library-api-documentation.html) - please claim issues prior to working on a specific scaladoc task to prevent duplication of effort. If you sit on an issue for too long without submitting a pull request, it will revert back to unassigned and you will need to re-claim it. +* [Claim Scaladoc Issues and Provide Documentation](/overviews/contribute/scala-standard-library-api-documentation.html) - please claim issues prior to working on a specific scaladoc task to prevent duplication of effort. If you sit on an issue for too long without submitting a pull request, it will revert back to unassigned and you will need to re-claim it. * You can also just -[submit new Scaladoc](/contribute/scala-standard-library-api-documentation.html) +[submit new Scaladoc](/overviews/contribute/scala-standard-library-api-documentation.html) without creating an issue, but please look to see if there is an issue already submitted for your task and claim it if there is. If not, please post your intention to work on a specific scaladoc task on [Scala Contributors](https://contributors.scala-lang.org/) so that people know what you are doing. ### The Main Scala Documentation Site @@ -45,7 +44,7 @@ without creating an issue, but please look to see if there is an issue already s * SIP (Scala Improvement Process) Proposals and more -Please read [contributing to the docs.scala-lang.org site](https://docs.scala-lang.org/contribute.html) through before embarking on changes. The site uses +Please read [contributing to the docs.scala-lang.org site](/contribute.html) through before embarking on changes. The site uses the [Jekyll](https://jekyllrb.com/) markdown engine so you will need to follow the instructions to get that running as well. ### Updating scala-lang.org @@ -56,4 +55,4 @@ to Scala and related projects) is provided on the main [scala-lang GitHub project](https://github.com/scala/scala-lang) which may be forked to create pull requests. Please read both the -[docs.scala-lang.org contribution](https://docs.scala-lang.org/contribute.html) document and the [scala-lang.org GitHub README](https://github.com/scala/scala-lang#scala-langorg) before embarking on any changes to the Scala language site, as it uses the same Jekyll markdown tool and many of the same conventions as the Scala documentation site. +[docs.scala-lang.org contribution](/contribute.html) document and the [scala-lang.org GitHub README](https://github.com/scala/scala-lang#scala-langorg) before embarking on any changes to the Scala language site, as it uses the same Jekyll markdown tool and many of the same conventions as the Scala documentation site. diff --git a/_overviews/contribute/guide.md b/_overviews/contribute/guide.md index 7cafd3d8a3..0b5b146ffc 100644 --- a/_overviews/contribute/guide.md +++ b/_overviews/contribute/guide.md @@ -4,7 +4,6 @@ layout: multipage-overview num: 9 partof: scala-contribution overview-name: Contributing to Scala -permalink: /contribute/guide.html ---
@@ -14,18 +13,18 @@ permalink: /contribute/guide.html

Get a peek into the inners of the Scala compiler.

-

Report an issue

+

Report an issue

File a bug report or a feature request.

-

Community issues

+

Community issues

Get cracking on some easy to approach issues.

-

Hacker guide

+

Hacker guide

Learn to write good code and improve your chances of contributing to the Scala galaxy.

@@ -56,22 +55,22 @@ unencumbered by copyrights or patents. This is the impatient developer's checklist for the steps to submit a bug-fix pull request to the Scala project. For more information, description and justification for the steps, follow the links in that step. Further specific instructions for the release of Scala you are targeting can be found in the `CONTRIBUTING.md` file for that [GitHub branch](https://github.com/scala/scala) -1. [Select a bug to fix from GitHub](/contribute/#community-tickets), or if you found the bug yourself and want to fix it, [create a GitHub issue](/contribute/bug-reporting-guide.html) (but please -[make sure it's not a duplicate](/contribute/bug-reporting-guide.html#reporting-confirmed-bugs-is-a-sin)). -2. Optional ([but recommended](/contribute/scala-internals/#why-its-a-good-idea)), announce your intention to work on the bug on [Scala Contributors](https://contributors.scala-lang.org/). After all, don't you want to work on a team with -[these friendly people](/contribute/hacker-guide.html#1-connect) - it's one of the perks of contributing. -3. [Fork the Scala repository](/contribute/hacker-guide.html#fork) and clone your fork (if you haven't already). -4. [Create a feature branch](/contribute/hacker-guide.html#branch) to work on: use the branch name `issue/NNNN` where NNNN is the GitHub issue number. -5. [Fix the bug, or implement the new small feature](/contribute/hacker-guide.html#implement), include new tests (yes, for bug fixes too). -6. [Test, rinse](/contribute/hacker-guide.html#test) and [test some more](/contribute/partest-guide.html) until [all the tests pass](/contribute/hacker-guide.html#verify). -7. [Commit your changes](/contribute/hacker-guide.html#commit) to your feature branch in your fork. Please choose your commit message based on the [Git Hygiene](https://github.com/scala/scala#user-content-git-hygiene) section of the Scala project README. +1. [Select a bug to fix from GitHub](/overviews/contribute/index.html#community-tickets), or if you found the bug yourself and want to fix it, [create a GitHub issue](/overviews/contribute/bug-reporting-guide.html) (but please +[make sure it's not a duplicate](/overviews/contribute/bug-reporting-guide.html#reporting-confirmed-bugs-is-a-sin)). +2. Optional ([but recommended](/overviews/contribute/scala-internals.html/#why-its-a-good-idea)), announce your intention to work on the bug on [Scala Contributors](https://contributors.scala-lang.org/). After all, don't you want to work on a team with +[these friendly people](/overviews/contribute/hacker-guide.html#1-connect) - it's one of the perks of contributing. +3. [Fork the Scala repository](/overviews/contribute/hacker-guide.html#fork) and clone your fork (if you haven't already). +4. [Create a feature branch](/overviews/contribute/hacker-guide.html#branch) to work on: use the branch name `issue/NNNN` where NNNN is the GitHub issue number. +5. [Fix the bug, or implement the new small feature](/overviews/contribute/hacker-guide.html#implement), include new tests (yes, for bug fixes too). +6. [Test, rinse](/overviews/contribute/hacker-guide.html#test) and [test some more](/overviews/contribute/partest-guide.html) until [all the tests pass](/overviews/contribute/hacker-guide.html#verify). +7. [Commit your changes](/overviews/contribute/hacker-guide.html#commit) to your feature branch in your fork. Please choose your commit message based on the [Git Hygiene](https://github.com/scala/scala#user-content-git-hygiene) section of the Scala project README. 8. If necessary [re-write git history](https://git-scm.com/book/en/Git-Branching-Rebasing) so that [commits are organized by major steps to the fix/feature]( https://github.com/scala/scala#git-hygiene). For bug fixes, a single commit is requested, for features several commits may be desirable (but each separate commit must compile and pass all tests) -9. [Submit a pull request](./hacker-guide.html#submit). -10. [Work with a reviewer](https://github.com/scala/scala#reviewing) to [get your pull request merged in](/contribute/hacker-guide.html#review). +9. [Submit a pull request](/overviews/contribute/hacker-guide.html#submit). +10. [Work with a reviewer](https://github.com/scala/scala#reviewing) to [get your pull request merged in](/overviews/contribute/hacker-guide.html#review). 11. Celebrate! -Need more information or a little more hand-holding for the first one? We got you covered: take a read through the entire [Hacker Guide](./hacker-guide.html) for an example of implementing a new feature (some of the steps can be skipped for bug fixes, this will be obvious from reading it, but many of the steps here will help with bug fixes too). +Need more information or a little more hand-holding for the first one? We got you covered: take a read through the entire [Hacker Guide](/overviews/contribute/hacker-guide.html) for an example of implementing a new feature (some of the steps can be skipped for bug fixes, this will be obvious from reading it, but many of the steps here will help with bug fixes too). ### Larger Changes, New Features @@ -80,4 +79,4 @@ and on the implementation plan. Announce the change on the [Scala Contributors](https://contributors.scala-lang.org/) mailing list and get developer feedback. For really complex changes, a [Scala Improvement Process (SIP)](https://docs.scala-lang.org/sips/) document might be required, but the first step is always to discuss it on the mailing list and if a SIP is required, that will be discussed on the mailing list. Contributions, big or small, simple or complex, controversial or undisputed, need to materialize as patches against -the Scala project source tree. The [hacker guide](/contribute/hacker-guide.html) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. +the Scala project source tree. The [hacker guide](/overviews/contribute/hacker-guide.html) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. diff --git a/_overviews/contribute/hacker-guide.md b/_overviews/contribute/hacker-guide.md index df659678cb..cb83b6218a 100644 --- a/_overviews/contribute/hacker-guide.md +++ b/_overviews/contribute/hacker-guide.md @@ -5,7 +5,6 @@ layout: multipage-overview num: 11 partof: scala-contribution overview-name: Contributing to Scala -permalink: /contribute/hacker-guide.html ---
This guide is intended to help you get from an idea of fixing a bug or implementing a new feature into a nightly Scala build, and, ultimately, to a production release of Scala incorporating your idea. @@ -32,7 +31,7 @@ Sometimes it's appealing to hack alone and not to have to interact with others o this might not be the very best idea. There are people in the Scala community who have spent years accumulating knowledge about Scala libraries and internals. They might provide unique insights and, what's even better, direct assistance in their areas, so it is not only advantageous, but recommended to communicate with the community about your new patch. -Typically bug fixes and new features start out as an idea or an experiment posted on one of [our mailing lists]({{ site.baseurl }}/community/index.html#forums) to find out how people feel +Typically bug fixes and new features start out as an idea or an experiment posted on one of [our mailing lists](https://scala-lang.org/community/index.html#forums) to find out how people feel about things you want to implement. People proficient in certain areas of Scala usually monitor mailing lists, so you'll often get some help by simply posting a message. But the most efficient way to connect is to cc your message to one of the people responsible for maintaining the aspect of Scala which you wish to contribute to. @@ -200,7 +199,7 @@ Contributing to the Scala standard library is about the same as working on one o If documentation is necessary for some trait/class/object/method/etc in the Scala standard library, typically maintainers will include inline comments describing their design decisions or rationale for implementing things the way they have, if it is not straightforward. -If you intend on contributing to Scala collections, please make sure you're familiar with the design of the Scala collections library. It can be easy to put an implementation in the wrong location if you are unfamiliar with the collections architecture. There is an excellent and very detailed guide covering [the Architecture of Scala Collections](https://docs.scala-lang.org/overviews/core/architecture-of-scala-collections.html), as well as a larger more general [Scala collections Guide](https://docs.scala-lang.org/overviews/collections/introduction.html) covering the sequential portion of collections. For parallel collections, there also exists a detailed [Scala Parallel Collections Guide](https://docs.scala-lang.org/overviews/parallel-collections/overview.html). +If you intend on contributing to Scala collections, please make sure you're familiar with the design of the Scala collections library. It can be easy to put an implementation in the wrong location if you are unfamiliar with the collections architecture. There is an excellent and very detailed guide covering [the Architecture of Scala Collections](/overviews/core/architecture-of-scala-collections.html), as well as a larger more general [Scala collections Guide](/overviews/collections/introduction.html) covering the sequential portion of collections. For parallel collections, there also exists a detailed [Scala Parallel Collections Guide](/overviews/parallel-collections/overview.html). ##### The Scala Compiler @@ -208,7 +207,7 @@ Documentation about the internal workings of the Scala compiler is scarce, and m * [Compiler internals videos by Martin Odersky](https://www.scala-lang.org/old/node/598.html) are quite dated, but still very useful. In this three-video series Martin explains the general architecture of the compiler, and the basics of the front-end, which has recently become Scala reflection API. -* [Reflection documentation](https://docs.scala-lang.org/overviews/reflection/overview.html) describes fundamental data structures (like `Tree`s, `Symbol`s, and `Types`) that +* [Reflection documentation](/overviews/reflection/overview.html) describes fundamental data structures (like `Tree`s, `Symbol`s, and `Types`) that are used to represent Scala programs and operations defined on then. Since much of the compiler has been factored out and made accessible via the Reflection API, all of the fundamentals needed for reflection are the same for the compiler. * [Reflection and Compilers by Martin Odersky](https://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Reflection-and-Compilers), a talk at Lang.NEXT 2012 in which Martin elaborates on the design of scalac and the architecture of the reflection API. @@ -266,7 +265,7 @@ Adding tests to the test suite is as easy as moving them to the appropriate dire * Code which should compile successfully, but doesn't need to be executed, needs to go into the [“pos” directory](https://github.com/scala/scala/tree/2.12.x/test/files/pos). * Code which should not compile needs to go into the [“neg” directory](https://github.com/scala/scala/tree/2.12.x/test/files/neg). -* Code which should compile and get executed by the test suite needs to go into the [“run” directory](https://github.com/scala/scala/tree/2.12.x/test/files/run) and have a corresponding `.check` file with the expected output. You will get test failures if the content of a `.check` file is different from what the test produces while running. If the change in the output is an expected product of your work, you might not want to change the `.check` file by hand. To make partest change the `.check` file, run it with a `--update-check` flag, like so `./test/partest --update-check path/to/test.scala`. For more information on partest, please refer to its [documentation](https://docs.scala-lang.org/tutorials/partest-guide.html). +* Code which should compile and get executed by the test suite needs to go into the [“run” directory](https://github.com/scala/scala/tree/2.12.x/test/files/run) and have a corresponding `.check` file with the expected output. You will get test failures if the content of a `.check` file is different from what the test produces while running. If the change in the output is an expected product of your work, you might not want to change the `.check` file by hand. To make partest change the `.check` file, run it with a `--update-check` flag, like so `./test/partest --update-check path/to/test.scala`. For more information on partest, please refer to its [documentation](https://github.com/scala/scala-partest). * Everything that can be unit-tested should go to ["junit" directory](https://github.com/scala/scala/tree/2.12.x/test/junit) * Property-based tests go to the ["scalacheck" directory](https://github.com/scala/scala/tree/2.12.x/test/scalacheck) @@ -311,7 +310,7 @@ This means your change is backward or forward binary incompatible with the speci ### Verify -Now to make sure that my fix doesn't break anything I need to run the test suite. The Scala test suite uses [JUnit](https://junit.org/junit4/) and [partest](partest-guide.html), a tool we wrote for testing Scala. +Now to make sure that my fix doesn't break anything I need to run the test suite. The Scala test suite uses [JUnit](https://junit.org/junit4/) and [partest](/overviews/contribute/partest-guide.html), a tool we wrote for testing Scala. Run `sbt test` and `sbt partest` to run all of the JUnit and partest tests, respectively. `partest` (not `sbt partest`) also allows you to run a subset of the tests using wildcards: diff --git a/_overviews/contribute/inclusive-language-guide.md b/_overviews/contribute/inclusive-language-guide.md index d673d57ad8..7f7c428f42 100644 --- a/_overviews/contribute/inclusive-language-guide.md +++ b/_overviews/contribute/inclusive-language-guide.md @@ -4,7 +4,6 @@ layout: multipage-overview num: 2 partof: scala-contribution overview-name: Contributing to Scala -permalink: /contribute/inclusive-language/ --- We are committed to providing a friendly, safe and welcoming environment for @@ -131,4 +130,4 @@ In those cases, we recommend to keep the old names, but document (e.g., in Scala ## See also -* Our [code of conduct](../../conduct/). +* Our [code of conduct](https://scala-lang.org/conduct/). diff --git a/_overviews/contribute/index.md b/_overviews/contribute/index.md index ac513b0009..8b7dad1e83 100644 --- a/_overviews/contribute/index.md +++ b/_overviews/contribute/index.md @@ -4,7 +4,6 @@ layout: multipage-overview num: 1 partof: scala-contribution overview-name: Contributing to Scala -permalink: /contribute/ --- The Scala programming language is an open source project with a very @@ -19,7 +18,7 @@ That depends on what you want to contribute. Below are some getting started reso ### Reporting bugs -See our [bug reporting guide](/contribute/bug-reporting-guide.html) to learn +See our [bug reporting guide](/overviews/contribute/bug-reporting-guide.html) to learn how to efficiently report a bug. ### Contribute @@ -33,8 +32,8 @@ Coordination of contribution efforts takes place on When contributing, please follow: -* The [Scala Code of Conduct](../conduct/) -* The [Inclusive Language Guide](./inclusive-language/) +* The [Scala Code of Conduct](https://scala-lang.org/conduct/) +* The [Inclusive Language Guide](/overviews/contribute/inclusive-language-guide.html) ### Community Tickets @@ -48,7 +47,7 @@ with their own maintainers and community of contributors. Helping out one of these projects is another way to help Scala. Consider lending on a hand on a project you're already using. Or, to find out about other projects, see the -[Libraries and Tools section](/community/#community-libraries-and-tools) +[Libraries and Tools section](https://scala-lang.org/community/#community-libraries-and-tools) on our Community page. ### Scala Community Build diff --git a/_overviews/contribute/partest-guide.md b/_overviews/contribute/partest-guide.md index 8f4dff394b..6fb5a2644b 100644 --- a/_overviews/contribute/partest-guide.md +++ b/_overviews/contribute/partest-guide.md @@ -4,7 +4,6 @@ layout: multipage-overview num: 12 partof: scala-contribution overview-name: Contributing to Scala -permalink: /contribute/partest-guide.html --- Partest is a custom parallel testing tool that we use to run the test suite for the Scala compiler and library. Go to the scala project folder from your local checkout and run it via `sbt`, `ant` or standalone as follows. diff --git a/_overviews/contribute/scala-internals.md b/_overviews/contribute/scala-internals.md index f52faa5c18..82346bcb15 100644 --- a/_overviews/contribute/scala-internals.md +++ b/_overviews/contribute/scala-internals.md @@ -4,7 +4,6 @@ layout: multipage-overview num: 8 partof: scala-contribution overview-name: Contributing to Scala -permalink: /contribute/scala-internals/ --- ## scala-internals diff --git a/_overviews/contribute/scala-standard-library-api-documentation.md b/_overviews/contribute/scala-standard-library-api-documentation.md index 97e3d708f9..977e733528 100644 --- a/_overviews/contribute/scala-standard-library-api-documentation.md +++ b/_overviews/contribute/scala-standard-library-api-documentation.md @@ -4,7 +4,6 @@ layout: multipage-overview num: 6 partof: scala-contribution overview-name: Contributing to Scala -permalink: /contribute/scala-standard-library-api-documentation.html --- This page is specific to API documentation contributions – that is, API @@ -13,8 +12,8 @@ documentation for sometimes referred to as Scaladoc contributions. For contributions to tutorial and guide-style documentation on -[docs.scala-lang.org](https://docs.scala-lang.org), -see the ["doc-site"'s contribution guide](https://docs.scala-lang.org/contribute.html). +[docs.scala-lang.org](/), +see the ["doc-site"'s contribution guide](/contribute.html). *Please note, these instructions cover documentation contributions Scala core libraries only. For other Scala projects please check those projects for the @@ -79,7 +78,7 @@ component so that they show up in the correct issue filters. Please familiarize yourself with the following before contributing new API documentation to save time, effort, mistakes and repetition. -* [Forking the Repo](./hacker-guide.html#2-set-up) - follow the setup steps through +* [Forking the Repo](/overviews/contribute/hacker-guide.html#2-set-up) - follow the setup steps through the Branch section. If providing new documentation related to an existing GitHub issue, use `issue/NNNN` or `ticket/NNNN` as the guide states. If providing API documentation with no associated GitHub issue, use `scaladoc/xxxx` instead. diff --git a/_overviews/contribute/tools.md b/_overviews/contribute/tools.md index 6df7c454a9..b7ae46b9ed 100644 --- a/_overviews/contribute/tools.md +++ b/_overviews/contribute/tools.md @@ -4,7 +4,6 @@ layout: multipage-overview num: 10 partof: scala-contribution overview-name: Contributing to Scala -permalink: /contribute/tools.html # Projects list: projects: @@ -23,7 +22,7 @@ projects: homeLink: https://www.scala-lang.org/api issuesLink: https://github.com/scala/bug/labels/scaladoc readmeLink: https://github.com/scala/scala#welcome - contributingLink: https://scala-lang.org/contribute/guide.html + contributingLink: /overviews/contribute/guide.html - title: Scala IDE description: Interactive build tool. icon: https://avatars2.githubusercontent.com/u/1026788?v=3&s=200 @@ -70,7 +69,7 @@ projectsInNeed: The links below are to a number of Scala build and IDE related projects that are important in the larger Scala space, and which welcome contributions. -Since these tools are in separate projects, they may (and likely will) have their own rules and guidelines for contributing. The [Hacker Guide](/contribute/hacker-guide.html) and [Bug-fixing](/contribute/guide.html) pages will likely have much in the way of related information on how to contribute to these projects, and are recommended reading. You should also check the README.md and (if it's present) CONTRIBUTING.md files from the actual projects before contributing to them. +Since these tools are in separate projects, they may (and likely will) have their own rules and guidelines for contributing. The [Hacker Guide](/overviews/contribute/hacker-guide.html) and [Bug-fixing](/overviews/contribute/guide.html) pages will likely have much in the way of related information on how to contribute to these projects, and are recommended reading. You should also check the README.md and (if it's present) CONTRIBUTING.md files from the actual projects before contributing to them. Typically, issues for these projects will be reported and kept in the GitHub project issue tracker for that project rather than in the Scala bug tracker. @@ -82,7 +81,7 @@ if you would like to help revive them. ### Broken Links? -Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](/contribute/documentation.html#updating-scala-langorg) to fix it. +Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](/overviews/contribute/documentation.html#updating-scala-langorg) to fix it. ### Projects From 9d9f0968e4635dc5eaf74cc0053b091e22eb2811 Mon Sep 17 00:00:00 2001 From: Antoine Pointeau Date: Mon, 21 Mar 2022 14:04:32 +0100 Subject: [PATCH 1802/3075] Translation for fr/extractor-objects (#2268) --- _fr/tour/extractor-objects.md | 58 +++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/_fr/tour/extractor-objects.md b/_fr/tour/extractor-objects.md index ac5c1dc013..9ffc529a58 100644 --- a/_fr/tour/extractor-objects.md +++ b/_fr/tour/extractor-objects.md @@ -3,10 +3,64 @@ layout: tour title: Extractor Objects partof: scala-tour -num: 14 +num: 18 language: fr -next-page: generic-classes +next-page: for-comprehensions previous-page: regular-expression-patterns --- + +Un objet extracteur est un objet avec une méthode `unapply`. Tandis que la méthode `apply` ressemble à un constructeur qui prend des arguments et crée un objet, `unapply` prend un object et essaye de retourner ses arguments. Il est utilisé le plus souvent en filtrage par motif (*pattern matching*) ou avec les fonctions partielles. + +```scala mdoc +import scala.util.Random + +object CustomerID { + + def apply(name: String) = s"$name--${Random.nextLong}" + + def unapply(customerID: String): Option[String] = { + val stringArray: Array[String] = customerID.split("--") + if (stringArray.tail.nonEmpty) Some(stringArray.head) else None + } +} + +val customer1ID = CustomerID("Sukyoung") // Sukyoung--23098234908 +customer1ID match { + case CustomerID(name) => println(name) // prints Sukyoung + case _ => println("Could not extract a CustomerID") +} +``` + +La méthode `apply` crée une chaîne de caractères `CustomerID` depuis `name`. La méthode `unapply` fait l'inverse pour retrouver le `name`. Lorsqu'on appelle `CustomerID("Sukyoung")`, c'est un raccourci pour `CustomerID.apply("Sukyoung")`. Lorsqu'on appelle `case CustomerID(name) => println(name)`, on appelle la méthode `unapply` avec `CustomerID.unapply(customer1ID)`. + +Sachant qu'une définition de valeur peut utiliser une décomposition pour introduire une nouvelle variable, un extracteur peut être utilisé pour initialiser la variable, avec la méthode `unapply` pour fournir la valeur. + +```scala mdoc +val customer2ID = CustomerID("Nico") +val CustomerID(name) = customer2ID +println(name) // prints Nico +``` + +C'est équivalent à `val name = CustomerID.unapply(customer2ID).get`. + +```scala mdoc +val CustomerID(name2) = "--asdfasdfasdf" +``` + +S'il n'y a pas de correspondance, une `scala.MatchError` est levée : + +```scala +val CustomerID(name3) = "-asdfasdfasdf" +``` + +Le type de retour de `unapply` doit être choisi comme suit : + +* Si c'est juste un test, retourner un `Boolean`. Par exemple, `case even()`. +* Si cela retourne une seule sous-valeur de type T, retourner un `Option[T]`. +* Si vous souhaitez retourner plusieurs sous-valeurs `T1,...,Tn`, groupez-les dans un tuple optionnel `Option[(T1,...,Tn)]`. + +Parfois, le nombre de valeurs à extraire n'est pas fixe et on souhaiterait retourner un nombre arbitraire de valeurs, en fonction des données d'entrée. Pour ce cas, vous pouvez définir des extracteurs avec la méthode `unapplySeq` qui retourne un `Option[Seq[T]]`. Un exemple commun d'utilisation est la déconstruction d'une liste en utilisant `case List(x, y, z) =>`. Un autre est la décomposition d'une `String` en utilisant une expression régulière `Regex`, comme `case r(name, remainingFields @ _*) =>`. + +Traduit par Antoine Pointeau. \ No newline at end of file From ef8f171b14742544916c206bada7517d7cb99d53 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Mon, 21 Mar 2022 14:32:32 +0100 Subject: [PATCH 1803/3075] modernise the content somewhat --- _contribute_resources/3-code-reviews.md | 1 + _overviews/contribute/bug-reporting-guide.md | 29 +++---- _overviews/contribute/codereviews.md | 47 ++++++----- _overviews/contribute/guide.md | 44 ++++------ _overviews/contribute/index.md | 2 +- _overviews/contribute/scala-internals.md | 84 +++++++++++-------- ...cala-standard-library-api-documentation.md | 9 +- _overviews/contribute/tools.md | 61 +++++--------- 8 files changed, 137 insertions(+), 140 deletions(-) diff --git a/_contribute_resources/3-code-reviews.md b/_contribute_resources/3-code-reviews.md index 41f6821414..e6f15e271c 100644 --- a/_contribute_resources/3-code-reviews.md +++ b/_contribute_resources/3-code-reviews.md @@ -4,5 +4,6 @@ link: /overviews/contribute/codereviews.html icon: fa fa-eye --- Review pull requests against [scala/scala](https://github.com/scala/scala/pulls), +[lampepfl/dotty](https://github.com/lampepfl/dotty/pulls), [scala/scala-lang](https://github.com/scala/scala-lang/pulls), [scala/docs.scala-lang](https://github.com/scala/docs.scala-lang/pulls) and others. diff --git a/_overviews/contribute/bug-reporting-guide.md b/_overviews/contribute/bug-reporting-guide.md index 5cbf0a3f46..9545ecdc53 100644 --- a/_overviews/contribute/bug-reporting-guide.md +++ b/_overviews/contribute/bug-reporting-guide.md @@ -6,7 +6,7 @@ partof: scala-contribution overview-name: Contributing to Scala --- -The Scala compiler and standard library bug tracker is located at [https://github.com/scala/bug](https://github.com/scala/bug). Before you submit a bug make sure that it is certainly a bug by following instructions in *Is it a Bug?*. +The Scala compiler and standard library bug tracker is located at [https://github.com/scala/bug](https://github.com/scala/bug), and for Scala 3, it is located at [github.com/lampepfl/dotty](https://github.com/lampepfl/dotty/issues). Before you submit a bug make sure that it is certainly a bug by following instructions in *Is it a Bug?*. ## Is it a Bug? @@ -22,7 +22,6 @@ If your issue is related to any of the following external projects, make sure to - [Akka](https://doc.akka.io/docs/akka/current/project/issue-tracking.html) - [Play!](https://github.com/playframework/Play20/issues) - [Slick](https://github.com/slick/slick/issues) - - [Scala IDE](https://scala-ide-portfolio.assembla.com/spaces/scala-ide/support/tickets) - [sbt](https://github.com/sbt/sbt/issues) The following are generally considered to be bugs: @@ -53,10 +52,10 @@ In general, if you find yourself stuck on any of these steps, asking on [Scala C - For compiler bugs use the [Compiler Category](https://contributors.scala-lang.org/c/compiler). * Examples of exceptions reported by the compiler which usually are not bugs: - 1. `StackOverflowError` is typically not a bug unless the stacktrace involves the internal packages of the compiler (like `scala.tools.nsc...`). Try to increase the Java stack size (`-Xss`), in most of the cases it helps. + 1. `StackOverflowError` is typically not a bug unless the stacktrace involves the internal packages of the compiler (like `scala.tools.nsc...`, or `dotty.tools.dotc...`). Try to increase the Java stack size (`-Xss`), in most of the cases it helps. 2. `AbstractMethodError` can occur when you did not recompile all the necessary Scala files (build tools, like `sbt`, can prevent that from happening) or you are mixing external libraries compiled for different Scala versions (for example one uses `2.10.x` and the other `2.11.x`). -## Reporting Confirmed Bugs is a Sin +## Please Check Before Reporting a Bug Before reporting your bug, make sure to check the issue tracker for other similar bugs. The exception name or a compiler phase are the best keywords to search for. If you are experiencing unexpected behavior search for method/class names where it happens. Your issue might already be reported, and a workaround might already be available for you take advantage of. If your issue *is* reported, be sure to add your test case as a comment if it is different from any of the existing ones. @@ -68,7 +67,7 @@ If you cannot find your issue in the issue tracker, create a new bug. The detail Please make sure to fill in as many fields as possible. Make sure you've indicated the following: - 1. **Exact Scala version** that you are using. For example, `2.10.1` or `2.11.0-RC`. If the bug happens in multiple versions indicate all of them. + 1. **Exact Scala version** that you are using. For example, `2.13.8` or `3.1.2-RC1`. If the bug happens in multiple versions indicate all of them. 2. **The component** that is affected by the bug. For example, the Standard Library, Scaladoc, etc. 3. **Labels** related to your issue. For example, if you think your issue is related to the typechecker, and if you have successfully minimized your issue, label your bug as "typechecker" and "minimized". Issue tracker will suggest names for existing labels as you type them so try not to create duplicates. 4. **Running environment**. Are you running on Linux? Windows? What JVM version are you using? @@ -78,12 +77,14 @@ In order for us to quickly triage the bug that you've found, it's important that ### Description In the description of your issue, be as detailed as you can. Bug reports which have the following information included are typically understood, triaged, and fixed very quickly: - - 1. Include a test case (minimized if possible) enabling us to reproduce the problematic behavior. Include your test case (and output) in proper formatting `{code}` blocks: - - {code}Here you put your classes{code} - - 2. The expected output. - 3. The actual output, including the stacktrace. - 4. Related discussion on the mailing lists, if applicable. - 5. If you have already looked into the issue provide interesting insights or proposals for fixing the issue. +1. Include a test case (minimized if possible) enabling us to reproduce the problematic behavior. Include your test +case (and output) in properly formatted code blocks: +~~~ +```scala +List(1, 2, 3).map(x => x + 1) +``` +~~~ +2. The expected output. +3. The actual output, including the stacktrace. +4. Related discussion on the mailing lists, if applicable. +5. If you have already looked into the issue provide interesting insights or proposals for fixing the issue. diff --git a/_overviews/contribute/codereviews.md b/_overviews/contribute/codereviews.md index 368bf96793..e7dea2acea 100644 --- a/_overviews/contribute/codereviews.md +++ b/_overviews/contribute/codereviews.md @@ -29,27 +29,32 @@ own pull requests. ## Pull Requests Awaiting Comment
-
-
-

scala/scala

-

Scala bug fixes and changes in the language, core libs and included tools.

-
-
-

scala/scala.github.com

-

Scala documentation site.

-
-
- -
-
-

scala/scala-lang

-

The Scala language web site.

-
-
-

All Scala GitHub Projects

-

For other PRs, follow the scala project from here.

-
-
+
+
+

lampepfl/dotty

+

Scala 3 bug fixes and changes in the language, core libs and included tools.

+
+
+

scala/scala

+

Scala 2 bug fixes and changes in the language, core libs and included tools.

+
+
+
+
+

scala/scala-lang

+

The Scala language web site.

+
+
+

scala/docs.scala-lang.org

+

Scala documentation site.

+
+
+
+
+

All Scala GitHub Projects

+

For other PRs, follow the scala project from here.

+
+
Also note that the [Tools contributions](/overviews/contribute/tools.html) page has more projects that will generate pull requests. diff --git a/_overviews/contribute/guide.md b/_overviews/contribute/guide.md index 0b5b146ffc..5acc188a27 100644 --- a/_overviews/contribute/guide.md +++ b/_overviews/contribute/guide.md @@ -6,29 +6,13 @@ partof: scala-contribution overview-name: Contributing to Scala --- -
-
-
-

Scala Contributors

-

Get a peek into the inners of the Scala compiler.

-
-
-

Report an issue

-

File a bug report or a feature request.

-
-
- -
-
-

Community issues

-

Get cracking on some easy to approach issues.

-
-
-

Hacker guide

-

Learn to write good code and improve your chances of contributing to the Scala galaxy.

-
-
-
+| **Shortcut** | **Description** | +|----------------------------------------|-----------------| +| [Scala Contributors][contrib-forum] | Get a peek into the inners of the Scala compiler. | +| [Report an Issue][bug-reporting-guide] | File a bug report or a feature request. | +| [Community Issues][community-tickets] | Get cracking on some easy to approach issues. | +| [Scala 2 Hacker's Guide][hackers] | Learn to write good code and improve your chances of contributing to the Scala galaxy. | +| [Scala 3 Contributing Guide][scala3-hackers] | Walkthrough contributing to the Scala 3 compiler, along with a guide to compiler internals. | @@ -52,11 +36,13 @@ which allows us to ensure that all code submitted to the project is unencumbered by copyrights or patents. ### Bug-fix Check List +> Originally these steps cover the [Scala 2 compiler](https://github.com/scala/scala), but they also are relevant to +> the [Scala 3 compiler](https://github.com/lampepfl/dotty). This is the impatient developer's checklist for the steps to submit a bug-fix pull request to the Scala project. For more information, description and justification for the steps, follow the links in that step. Further specific instructions for the release of Scala you are targeting can be found in the `CONTRIBUTING.md` file for that [GitHub branch](https://github.com/scala/scala) 1. [Select a bug to fix from GitHub](/overviews/contribute/index.html#community-tickets), or if you found the bug yourself and want to fix it, [create a GitHub issue](/overviews/contribute/bug-reporting-guide.html) (but please -[make sure it's not a duplicate](/overviews/contribute/bug-reporting-guide.html#reporting-confirmed-bugs-is-a-sin)). +[make sure it's not a duplicate](/overviews/contribute/bug-reporting-guide.html#please-check-before-reporting-a-bug)). 2. Optional ([but recommended](/overviews/contribute/scala-internals.html/#why-its-a-good-idea)), announce your intention to work on the bug on [Scala Contributors](https://contributors.scala-lang.org/). After all, don't you want to work on a team with [these friendly people](/overviews/contribute/hacker-guide.html#1-connect) - it's one of the perks of contributing. 3. [Fork the Scala repository](/overviews/contribute/hacker-guide.html#fork) and clone your fork (if you haven't already). @@ -70,7 +56,7 @@ https://github.com/scala/scala#git-hygiene). For bug fixes, a single commit is r 10. [Work with a reviewer](https://github.com/scala/scala#reviewing) to [get your pull request merged in](/overviews/contribute/hacker-guide.html#review). 11. Celebrate! -Need more information or a little more hand-holding for the first one? We got you covered: take a read through the entire [Hacker Guide](/overviews/contribute/hacker-guide.html) for an example of implementing a new feature (some of the steps can be skipped for bug fixes, this will be obvious from reading it, but many of the steps here will help with bug fixes too). +Need more information or a little more hand-holding for the first one? We got you covered: take a read through the entire [Hacker Guide][hackers] (or the [equivalent Scala 3 Contributing Guide][scala3-hackers]) for an example of implementing a new feature (some of the steps can be skipped for bug fixes, this will be obvious from reading it, but many of the steps here will help with bug fixes too). ### Larger Changes, New Features @@ -79,4 +65,10 @@ and on the implementation plan. Announce the change on the [Scala Contributors](https://contributors.scala-lang.org/) mailing list and get developer feedback. For really complex changes, a [Scala Improvement Process (SIP)](https://docs.scala-lang.org/sips/) document might be required, but the first step is always to discuss it on the mailing list and if a SIP is required, that will be discussed on the mailing list. Contributions, big or small, simple or complex, controversial or undisputed, need to materialize as patches against -the Scala project source tree. The [hacker guide](/overviews/contribute/hacker-guide.html) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. +the Scala project source tree. The hacker's guides ([Scala 2][hackers], or [Scala 3][scala3-hackers]) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. + +[hackers]: /overviews/contribute/hacker-guide.html +[community-tickets]: /overviews/contribute/index.html#community-tickets +[bug-reporting-guide]: /overviews/contribute/bug-reporting-guide.html +[scala3-hackers]: {% link _overviews/scala3-contribution/procedures-intro.md %} +[contrib-forum]: https://contributors.scala-lang.org/ diff --git a/_overviews/contribute/index.md b/_overviews/contribute/index.md index 8b7dad1e83..b89f04803a 100644 --- a/_overviews/contribute/index.md +++ b/_overviews/contribute/index.md @@ -37,7 +37,7 @@ When contributing, please follow: ### Community Tickets -All issues can be found in the [Scala bug tracker](https://github.com/scala/bug). Most issues are labeled +All issues can be found in the [Scala bug tracker](https://github.com/scala/bug), or the [Scala 3 issue tracker](https://github.com/lampepfl/dotty/issues). Most issues are labeled to make it easier to find issues you are interested in. ### Tools and Libraries diff --git a/_overviews/contribute/scala-internals.md b/_overviews/contribute/scala-internals.md index 82346bcb15..ac5be2fd85 100644 --- a/_overviews/contribute/scala-internals.md +++ b/_overviews/contribute/scala-internals.md @@ -1,47 +1,63 @@ --- -title: Scala Internals Mailing List +title: Scala Contributors Forum layout: multipage-overview num: 8 partof: scala-contribution overview-name: Contributing to Scala --- -## scala-internals - -The [scala-internals mailing list](https://groups.google.com/d/forum/scala-internals) is where technical and logistical discussions concerning bugs, bug fixes, documentation, improvements, new features and other contributor related topics occur. - -### Coordinating on scala-internals - -Prior to commencing on contribution work on larger changes to the Scala project, it is recommended (but not required) that you make a post on scala-internals announcing your intention. It's a great time to invite any help, advice or ask any questions you might have. It's also a great place to meet peers, one of whom will probably be reviewing your contribution at some point. For smaller bug fixes or documentation changes where the risk of effort duplication is minimal, you can skip this post. - -To help subscribers on the scala-internals list to sort through the postings, we request that the following topic labels are applied when you start a new post please: - -| Label | Topics | -|-----------|-------------------------------------------------------| -| [docs] | Documentation, e.g. docs.scala-lang.org, API (scaladoc), etc. | -| [issues] | Bug reporting/fixing | -| [tools] | Tools including sbt, IDE plugins, testing, scaladoc generator, etc. | -| [libs] | Core libraries, extension libraries | -| [compiler] | Scala compiler discussions/features/issues | -| [admin] | Administrative/coordination topics | - -So, to talk about this list (an admin activity primarily) one might use: - -`[admin] more suggested labels for topic differentiation.` - -as a title, which then shows up on the mailing lists as - -`[scala-internals] [admin] more suggested labels for topic differentiation.` +The [Scala Contributors Forum][scala-contributors] is where discussions about the Scala ecosystem +occur, from the perspectives of core compiler, documentation and library contributors. It features updates from the +Scala Center, along with technical and logistical discussions concerning bugs, bug fixes, documentation, improvements, +new features and other contributor related topics. + +> The now legacy [scala-internals mailing list](https://groups.google.com/d/forum/scala-internals) used to fulfil this +> purpose, but has since expanded to encompass more topics in the new [forum][scala-contributors]. + +## Coordinating on Scala Contributors + +Prior to commencing on contribution work on larger changes to the Scala project, it is recommended (but not required) +that you make a post on [Scala Contributors][scala-contributors] announcing your intention. +It's a great time to invite any help, advice or ask any questions you might have. It's also a great place to meet peers, +one of whom will probably be reviewing your contribution at some point. +For smaller bug fixes or documentation changes where the risk of effort duplication is minimal, you can skip this post. + +To help users to sort through the posts, we request that the following categories are applied when you start a +new post please: + +| Category | Topics | +|-----------------------------|---------------------------------------------------------------------| +| `Documentation` | Documentation, e.g. docs.scala-lang.org, API (scaladoc), etc. | +| `Compiler` | Bug reporting/fixing, Scala compiler discussions/issues | +| `Tooling` | Tools including sbt, IDE plugins, testing, scaladoc generator, etc. | +| `Scala Standard Library` | Core libraries | +| `Scala Platform` | Extension libraries | +| `Language Design` | Scala language feature discussions / informal proposals | +| `Scala Improvement Process` | Scala language feature formal proposals | +| `Meta Discourse` | Administrative/coordination topics | +| `Community` | Discussions about events, community organising | ### Why It's a Good Idea -While it is optional to announce your intentions/work items on scala-internals before starting, it is recommended and a smart thing to do for a number of reasons: +While it is optional to announce your intentions/work items on [Scala Contributors][scala-contributors] before starting, it is recommended thing to do for a number of reasons: * To attempt to cut down on duplicate effort (i.e. to avoid two people working on the same bug at the same time without coordinating effort). * Related to the above: to allow the compiler team and core committers to warn of or smooth over potential merge conflicts between separate bugs that might affect the same code. -* Potentially someone has already thought about or even worked on that issue or a related one, and has valuable insight that might save you time (including warnings about what you might find and may want to avoid - dead ends that have already been explored). -* You might find a group of impassioned individuals want to volunteer to help you, since you got there first with your post it's up to you to decide if you want help or not. -* Posting could start a dialog with a potential reviewer, smoothing the latter, merge stages of the issue. -* There are a lot of nice people waiting to talk to you on scala-internals, you might be surprised how valuable and pleasant you find the experience of talking to them. - -If all of this has not convinced you then, please, go ahead and work on contributions anyway. It *is* less important to post to scala-internals first for small, self contained bugs than it is for larger issues or features, and not having posted first will not be a reason for your PR to be rejected, it just might be a rougher review/merge process than if you had posted first. It's your choice. +* Potentially someone has already thought about or even worked on that issue or a related one, and has valuable insight +that might save you time (including warnings about what you might find and may want to avoid - perhaps one option +already tried lead to no benefit). +* You might find a group of impassioned individuals who want to volunteer and help you. You will have the momentum since +you posted first, so then it's up to you to decide if you want their help or not. +* Posting could start a dialog with a potential reviewer, smoothing the later stages of your contribution before +merging your changes. +* There are a lot of nice people waiting to talk to you on [Scala Contributors][scala-contributors], you might be +surprised how valuable and pleasant you find the experience of talking to them. + +Even if you do not wish to post on [Scala Contributors][scala-contributors], please feel welcome to make contributions +anyway, as posting to the forum is *not* criteria for it to be accepted. For smaller, self-contained bugs it is +especially less important to make a post, however larger issues or features take more time to consider accepting them. +For large contributions we strongly recommend that you do to notify of your intention, which will help you determine if +there is large community support for your change, making it more likely that your large contribution will accepted, +before you spend a long time implementing it. + +[scala-contributors]: https://contributors.scala-lang.org diff --git a/_overviews/contribute/scala-standard-library-api-documentation.md b/_overviews/contribute/scala-standard-library-api-documentation.md index 977e733528..ba59855392 100644 --- a/_overviews/contribute/scala-standard-library-api-documentation.md +++ b/_overviews/contribute/scala-standard-library-api-documentation.md @@ -43,7 +43,8 @@ and identify missing, incorrect or inadequate documentation. A good place to sta package objects for important packages (these often get overlooked for documentation and are a good place for API overviews). -If you find an issue, please log it in the [Scala bug tracker](https://github.com/scala/bug) +If you find an issue, please log it in the [Scala bug tracker](https://github.com/scala/bug), +(or else the [Scala 3 issue tracker](https://github.com/lampepfl/dotty/issues) for Scala 3 library additions) **after making sure it is not already logged as an issue**. To help with disambiguation, please use the following format for issue title: @@ -112,10 +113,10 @@ PR is merged in smoothly: Scala code is likely to flag as mis-spelled sometimes, but any written language should be checked. If you can also use a grammar checker, even better. We *will* ask for spelling and grammar to be corrected before acceptance. -* You **must** also run `ant docs`, fix any problems and check the formatting and +* You **must** also run `sbt doc`, fix any problems and check the formatting and layout of your changes. Again, corrections will be required if formatting or - layout are inadequate. After running `ant docs` the generated documents can be - found under the `build/scaladoc/` folders (probably in the `library` folder + layout are inadequate. After running `sbt doc` the generated documents can be + found under the `build/scaladoc/` folders (probably in the `library` subdirectory but maybe under the others depending on what section of the Scala source you are working on). * All of these steps are required to save time for both the reviewers and diff --git a/_overviews/contribute/tools.md b/_overviews/contribute/tools.md index b7ae46b9ed..4ce5a3be0a 100644 --- a/_overviews/contribute/tools.md +++ b/_overviews/contribute/tools.md @@ -8,8 +8,8 @@ overview-name: Contributing to Scala # Projects list: projects: - title: sbt - description: Interactive build tool. - icon: https://www.scala-sbt.org/assets/typesafe_sbt_svg.svg + description: The interactive build tool. + icon: https://www.scala-sbt.org/assets/sbt-logo.svg link: https://github.com/sbt/sbt homeLink: https://www.scala-sbt.org/ issuesLink: https://github.com/sbt/sbt#issues-and-pull-requests @@ -23,57 +23,26 @@ projects: issuesLink: https://github.com/scala/bug/labels/scaladoc readmeLink: https://github.com/scala/scala#welcome contributingLink: /overviews/contribute/guide.html - - title: Scala IDE - description: Interactive build tool. - icon: https://avatars2.githubusercontent.com/u/1026788?v=3&s=200 - link: https://github.com/scala-ide/scala-ide - homeLink: http://scala-ide.org/ - issuesLink: https://scala-ide-portfolio.assembla.com/spaces/scala-ide/support/tickets - readmeLink: https://github.com/scala-ide/scala-ide/blob/master/README.md - contributingLink: https://github.com/scala-ide/scala-ide/blob/master/CONTRIBUTING.md - - title: DBuild - description: Multi-project build tool. - icon: https://avatars3.githubusercontent.com/u/784923?v=3&s=200 - link: https://github.com/lightbend/dbuild - homeLink: https://lightbend.github.io/dbuild - issuesLink: https://github.com/lightbend/dbuild/issues - readmeLink: https://github.com/lightbend/dbuild/blob/master/README.md - contributingLink: https://github.com/lightbend/dbuild/blob/master/README.md#get-involved - title: Partest - description: Scala Compiler/Library Testing + description: Scala Compiler/Library Testing (Contribute through scala/scala) icon: https://avatars1.githubusercontent.com/u/57059?v=3&s=200 - link: https://github.com/scala/scala-partest - homeLink: https://docs.scala-lang.org/tutorials/partest-guide.html - issuesLink: https://github.com/scala/scala-partest/issues - readmeLink: https://github.com/scala/scala-partest/blob/1.1.x/README.md + link: https://github.com/scala/scala + homeLink: https://github.com/scala/scala + issuesLink: https://github.com/scala/scala/issues + readmeLink: https://github.com/scala/scala/blob/2.13.x/CONTRIBUTING.md#partest contributingLink: - - title: Scoverage - description: Scala code coverage tool - icon: https://avatars1.githubusercontent.com/u/5998302?v=3&s=200 - link: https://github.com/scoverage/scalac-scoverage-plugin - homeLink: http://scoverage.org/ - issuesLink: https://github.com/scoverage/scalac-scoverage-plugin/issues - readmeLink: https://github.com/scoverage/scalac-scoverage-plugin/blob/master/README.md - contributingLink: https://groups.google.com/forum/#!forum/scala-code-coverage-tool projectsInNeed: - - title: Scalariform - description: Scala source code formatter - icon: /resources/img/white-line.png - link: https://github.com/mdr/scalariform - homeLink: https://github.com/mdr/scalariform/wiki/Command-line-tool - issuesLink: https://github.com/mdr/scalariform/issues - readmeLink: https://github.com/mdr/scalariform/blob/master/README.rst --- ## Contributing to IDE and Build Tools The links below are to a number of Scala build and IDE related projects that are important in the larger Scala space, and which welcome contributions. -Since these tools are in separate projects, they may (and likely will) have their own rules and guidelines for contributing. The [Hacker Guide](/overviews/contribute/hacker-guide.html) and [Bug-fixing](/overviews/contribute/guide.html) pages will likely have much in the way of related information on how to contribute to these projects, and are recommended reading. You should also check the README.md and (if it's present) CONTRIBUTING.md files from the actual projects before contributing to them. +Since these tools are in separate projects, they may (and likely will) have their own rules and guidelines for contributing. You should also check the `README.md` and (if it's present) `CONTRIBUTING.md` files from the actual projects before contributing to them. Typically, issues for these projects will be reported and kept in the GitHub project issue tracker for that project rather than in the Scala bug tracker. -Many of these projects have a chat room on Discord or Gitter (usually linked from their README or CONTRIBUTING files) which is a great place to discuss proposed work before starting. +Many of these projects have a chat room on Discord or Gitter (usually linked from their `README.md` or `CONTRIBUTING.md` files) which is a great place to discuss proposed work before starting. There are some projects in this section that are in [particular need](#projects-in-particular-need) so please check those out @@ -85,10 +54,22 @@ Stuff changes. Found a broken link or something that needs updating on this page ### Projects +{% if page.projects.size > 0 %} {% include contributions-projects-list.html collection=page.projects %} +{% else %} +There are no projects. +{% endif %} ### Projects in Particular Need +{% if page.projectsInNeed.size > 0 %} + The following projects are important to the Scala community but are particularly in need of contributors to continue their development. {% include contributions-projects-list.html collection=page.projectsInNeed %} + +{% else %} + +There are no projects in particular need. + +{% endif %} From b32fe5627023d8c45d20a1fcf20c20ae3e70e7b0 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Mon, 21 Mar 2022 14:47:11 +0100 Subject: [PATCH 1804/3075] add new page - Add New Guides/Tutorials --- README.md | 2 +- _contribute_resources/1-documentation.md | 2 +- _overviews/contribute/add-guides.md | 221 ++++++++++++++++++ _overviews/contribute/bug-reporting-guide.md | 2 +- _overviews/contribute/documentation.md | 4 +- _overviews/contribute/guide.md | 2 +- _overviews/contribute/hacker-guide.md | 2 +- _overviews/contribute/partest-guide.md | 2 +- _overviews/contribute/scala-internals.md | 2 +- ...cala-standard-library-api-documentation.md | 2 +- _overviews/contribute/tools.md | 2 +- contribute.md | 179 +------------- 12 files changed, 237 insertions(+), 185 deletions(-) create mode 100644 _overviews/contribute/add-guides.md diff --git a/README.md b/README.md index a6283b2386..ee37fe58d4 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ For more details on the Docker option, see [this issue](https://github.com/scala ## Contributing ## -Please have a look at [https://docs.scala-lang.org/contribute.html](https://docs.scala-lang.org/contribute.html) before making a contribution. +Please have a look at [Add New Guides/Tutorials](https://docs.scala-lang.org/overviews/contribute/add-guides.html) before making a contribution. This document gives an overview of the type of documentation contained within the Scala Documentation repository and the repository's structure. Small changes, or corrected typos will generally be pulled in right away. Large changes, like the addition of new documents, or the rewriting of diff --git a/_contribute_resources/1-documentation.md b/_contribute_resources/1-documentation.md index 3e1b81a7b9..7515ff7519 100644 --- a/_contribute_resources/1-documentation.md +++ b/_contribute_resources/1-documentation.md @@ -3,4 +3,4 @@ title: Documentation link: /overviews/contribute/documentation.html icon: fa fa-book --- -[Scaladoc (API)](/overviews/contribute/scala-standard-library-api-documentation.html), [docs.scala-lang.org](/contribute.html) and [scala-lang.org](https://github.com/scala/scala-lang). +[Scaladoc (API)](/overviews/contribute/scala-standard-library-api-documentation.html), [docs.scala-lang.org](/overviews/contribute/add-guides.html) and [scala-lang.org](https://github.com/scala/scala-lang). diff --git a/_overviews/contribute/add-guides.md b/_overviews/contribute/add-guides.md new file mode 100644 index 0000000000..c8f5e42f0c --- /dev/null +++ b/_overviews/contribute/add-guides.md @@ -0,0 +1,221 @@ +--- +title: Add New Guides/Tutorials +layout: multipage-overview +num: 7 +partof: scala-contribution +overview-name: Contributing to Scala +--- + +## Why Contribute New Learning Material? + +As [Heather Miller writes](/contribute.html), contributing to [docs.scala-lang.org](https://docs.scala-lang.org) is +critical to making Scala accessible to newcomers, experience programmers, and anyone who is curious. +It is also a fantastic way to contribute for anyone who is comfortable using Scala, but maybe does not want to get +involved with complex tools like the compiler. + +## Architecture + +This documentation website is backed by an open-source [github repository](https://github.com/scala/docs.scala-lang), +and is always contribution-ready. + +### Content + +Currently, the _types_ of documentation supported in this repository are: + +- **Guides/Overviews**: Definitive guides/overviews of specific language features. Often long, detailed documents, + often produced by members of the Scala team. An example is the excellent [Collections][collections-overview] overview. +- **Tutorials**: Bite-size, example-rich, and concise articles meant to get a developer up to speed quickly. +- **Cheatsheets**: Quick reference of Scala syntax and behaviors. + +### Implementation + +The website is statically generated from [Markdown](https://en.wikipedia.org/wiki/Markdown) source using +[Jekyll](https://github.com/mojombo/jekyll), and hosted on [GitHub Pages](https://pages.github.com/). +This workflow was chosen so as to make it as easy as possible for core committers and the community alike +to produce HTML documentation, and as easy as possible to publish it in a central location. + +The markdown syntax being used supports [Maruku](https://github.com/bhollis/maruku) extensions, and has automatic +syntax highlighting, without the need for any tags. + +Additionally [mdoc](https://github.com/scalameta/mdoc) is used during pull requests to validate Scala code blocks. +To use this feature you must use the backtick notation as documented by mdoc. Note that only validation is done. +The output files from mdoc are not used in the building of the tutorial. Use `mdoc` or `mdoc:fail` for your code blocks. + +## Submitting Docs + +For one to contribute a document, one must simply +[fork](https://help.github.com/articles/fork-a-repo/) the +[repo](https://github.com/scala/docs.scala-lang), write their article in +[Markdown](https://daringfireball.net/projects/markdown/syntax) (example below), and submit a pull request. That's it. +Likely after some edits and discussion, your document will be made live +on [docs.scala-lang.org](https://docs.scala-lang.org). + + --- + layout: overview + title: My Awesome Title + --- + + ## An h2 Header in Markdown + + And a paragraph, with a [link](https://www.scala-lang.org). + +One can contribute code in a markdown document by either + - indenting it by 4 spaces + - surrounding by triple backticks, as shown below + - in-line by putting backticks around it, e.g. `def foo`. + + ```scala + println("hello") + ``` + +Everything else is automatically generated for you; tables of contents, and most index pages. And of course, the +styling is already taken care of for you. + +### Criteria for Docs to be Accepted + +The goal of this documentation repository is to be tighter and more organized than other community-driven documentation platforms, like wikis. As such, any document pulled in for inclusion on +[docs.scala-lang.org](https://docs.scala-lang.org) must: + +- **"fit in"** to the repository ( _i.e.,_ it should not be a complete duplicate of another article), +- **be polished** it must be thorough, complete, correct, organized, and "article-like" (personal programming notes +don't quite fit.) +- **be maintained** if the document might require revisions from time to time, be prepared to keep it up to date, or +nominate someone to take ownership. + +If you have something you're thinking about contributing, or that you're thinking about writing in order to contribute +-- we'd love to consider it! Please don't hesitate to use GitHub issues and pull requests and the +\#scala-contributors room [on Discord](https://discord.com/invite/scala) for any questions, concerns, +clarifications, etc. + +## Document Templates + +> **Note:** These templates will soon change slightly as a result of necessary refactoring. + +### Guides/Overviews + +A guide or an overview that can be logically placed on **one** page must be placed in the directory +`_overviews/RELEVANT-CATEGORY/_posts` with the file name in the format `YYYY-MM-dd-title-separated-by-dashes.md`, +and header: + + --- + layout: overview + title: YOUR TITLE + --- + +The rest of the document should, of course, be written in [Markdown](https://en.wikipedia.org/wiki/Markdown). + +At the moment, `RELEVANT-CATEGORY` corresponds to only a single category, "core," because we are currently focusing on +building up documentation of core libraries. However, expect more categories here in the future. + +If your document consists of **multiple** pages, like the [Collections][collections-overview] overview, an ordering +must be specified, by numbering documents in their logical order with `num`, and a name must be assigned to the +collection of pages using `partof`. For example, the following header might be used for a document in the collections +overview: + + --- + layout: overview + title: YOUR TITLE + + partof: collections + num: 10 + --- + +A **single** document in the collection must contain a tag in the header, `outof`, that indicates the total number of +documents in the large overview. Putting it on the last page in the overview is often best: + + --- + layout: overview + title: YOUR TITLE + + partof: collections + num: 15 + outof: 15 + --- + +Index pages, such as [docs.scala-lang.org/overviews/index.html](https://docs.scala-lang.org/overviews/index.html) are +generated, by reading data from a configuration file, such as `_data/overviews.yml`, so your overview should be +placed into a category there. + +### Tutorials + +At the moment, tutorials are written the same as Guides/Overviews, except that their link must be added to +the metadata of `/tutorials.md`. e.g. for the [Scala With Maven][scala-with-maven] tutorial, the +metadata of `/tutorials.md` looks like + + --- + layout: inner-page-parent + title: Tutorials + + tutorials: + ... + - title: "Scala with Maven" + url: "/tutorials/scala-with-maven.html" + description: "Create a Scala project with Maven." + icon: code + --- + +For a single-page tutorial, the typical directory to place them in is `_overviews/tutorials`. + +### Cheatsheets + +For now, cheatsheets are assumed to be in the form of tables. To contribute a cheatsheet, one must simply produce their +cheatsheet as a Markdown table, with the following header: + + --- + layout: cheatsheet + title: YOUR TITLE + by: YOUR NAME + about: SOME TEXT ABOUT THE CHEAT SHEET. + --- + +### Code blocks + +The site build process uses [mdoc](https://scalameta.org/mdoc/) to typecheck +code snippets in markdown. This is a great way to ensure the code snippets that +you're including typecheck and are valid. Here are a few quick types to get +started. + +To get started, add `mdoc` after `scala` when you are creating a +code block. The `mdoc` modifier here will make sure that `mdoc` runs the code +snippet and ensures that it's valid. + + ```scala mdoc + val a = 1 + ``` +If you have a snippet that you expect to fail, you can also account for this by +using `mdoc:fail` for a compile error `mdoc:crash` for a runtime-error. + + ```scala mdoc:fail + val b: String = 3 // won't compile + ``` +Keep in mind that a single file is all compiled as a single unit, so you can't +redefine a variable that was defined above in another code snippet. _However_ +there are a couple ways to get around this. Firstly, you can use the `mdoc:nest` +modifier with will wrap the snippet in a `scala.Predef.locally{...}`. This will +essentially "hide" the snippet from the others. Another way around this is to +use the `mdoc:reset` modifier, which _resets_ and forgets about everything up +above. Here is an example using the various modifiers. + + ```scala mdoc + import java.time.Instant + + def now() = Instant.now() + object Foo {} + ``` + + ```scala mdoc:nest + case class Foo(a: Int) // conflicts with Foo above, but it's nested so it's fine + ``` + + ```scala mdoc + val a = s"The time is ${now()}" // still have access to the now method from above + ``` + ```scala mdoc:reset + case class Foo(a: String) // forget the previous Foo's and start fresh + ``` + ```scala mdoc + val myFoo = Foo("hi") // now we only have access to the last Foo + ``` + +[collections-overview]: {% link _overviews/collections-2.13/introduction.md %} +[scala-with-maven]: {% link _overviews/tutorials/scala-with-maven.md %} diff --git a/_overviews/contribute/bug-reporting-guide.md b/_overviews/contribute/bug-reporting-guide.md index 9545ecdc53..ac6df525a5 100644 --- a/_overviews/contribute/bug-reporting-guide.md +++ b/_overviews/contribute/bug-reporting-guide.md @@ -1,7 +1,7 @@ --- title: Bug Reporting Guide layout: multipage-overview -num: 7 +num: 8 partof: scala-contribution overview-name: Contributing to Scala --- diff --git a/_overviews/contribute/documentation.md b/_overviews/contribute/documentation.md index 7fca82ff53..417f9b234a 100644 --- a/_overviews/contribute/documentation.md +++ b/_overviews/contribute/documentation.md @@ -44,7 +44,7 @@ without creating an issue, but please look to see if there is an issue already s * SIP (Scala Improvement Process) Proposals and more -Please read [contributing to the docs.scala-lang.org site](/contribute.html) through before embarking on changes. The site uses +Please read [Add New Guides/Tutorials](/overviews/contribute/add-guides.html) through before embarking on changes. The site uses the [Jekyll](https://jekyllrb.com/) markdown engine so you will need to follow the instructions to get that running as well. ### Updating scala-lang.org @@ -55,4 +55,4 @@ to Scala and related projects) is provided on the main [scala-lang GitHub project](https://github.com/scala/scala-lang) which may be forked to create pull requests. Please read both the -[docs.scala-lang.org contribution](/contribute.html) document and the [scala-lang.org GitHub README](https://github.com/scala/scala-lang#scala-langorg) before embarking on any changes to the Scala language site, as it uses the same Jekyll markdown tool and many of the same conventions as the Scala documentation site. +[Add New Guides/Tutorials](/overviews/contribute/add-guides.html) document and the [scala-lang.org GitHub README](https://github.com/scala/scala-lang#scala-langorg) before embarking on any changes to the Scala language site, as it uses the same Jekyll markdown tool and many of the same conventions as the Scala documentation site. diff --git a/_overviews/contribute/guide.md b/_overviews/contribute/guide.md index 5acc188a27..802e3c387c 100644 --- a/_overviews/contribute/guide.md +++ b/_overviews/contribute/guide.md @@ -1,7 +1,7 @@ --- title: Contributing guide layout: multipage-overview -num: 9 +num: 10 partof: scala-contribution overview-name: Contributing to Scala --- diff --git a/_overviews/contribute/hacker-guide.md b/_overviews/contribute/hacker-guide.md index cb83b6218a..f342c98040 100644 --- a/_overviews/contribute/hacker-guide.md +++ b/_overviews/contribute/hacker-guide.md @@ -2,7 +2,7 @@ title: Scala hacker guide by: Eugene Burmako layout: multipage-overview -num: 11 +num: 12 partof: scala-contribution overview-name: Contributing to Scala --- diff --git a/_overviews/contribute/partest-guide.md b/_overviews/contribute/partest-guide.md index 6fb5a2644b..548eb8d5e6 100644 --- a/_overviews/contribute/partest-guide.md +++ b/_overviews/contribute/partest-guide.md @@ -1,7 +1,7 @@ --- title: Running the Test Suite layout: multipage-overview -num: 12 +num: 13 partof: scala-contribution overview-name: Contributing to Scala --- diff --git a/_overviews/contribute/scala-internals.md b/_overviews/contribute/scala-internals.md index ac5be2fd85..5f391947fa 100644 --- a/_overviews/contribute/scala-internals.md +++ b/_overviews/contribute/scala-internals.md @@ -1,7 +1,7 @@ --- title: Scala Contributors Forum layout: multipage-overview -num: 8 +num: 9 partof: scala-contribution overview-name: Contributing to Scala --- diff --git a/_overviews/contribute/scala-standard-library-api-documentation.md b/_overviews/contribute/scala-standard-library-api-documentation.md index ba59855392..99f1bb16e0 100644 --- a/_overviews/contribute/scala-standard-library-api-documentation.md +++ b/_overviews/contribute/scala-standard-library-api-documentation.md @@ -13,7 +13,7 @@ sometimes referred to as Scaladoc contributions. For contributions to tutorial and guide-style documentation on [docs.scala-lang.org](/), -see the ["doc-site"'s contribution guide](/contribute.html). +see [Add New Guides/Tutorials](/overviews/contribute/add-guides.html). *Please note, these instructions cover documentation contributions Scala core libraries only. For other Scala projects please check those projects for the diff --git a/_overviews/contribute/tools.md b/_overviews/contribute/tools.md index 4ce5a3be0a..875160ca96 100644 --- a/_overviews/contribute/tools.md +++ b/_overviews/contribute/tools.md @@ -1,7 +1,7 @@ --- title: IDE and Build Tool Contributions layout: multipage-overview -num: 10 +num: 11 partof: scala-contribution overview-name: Contributing to Scala diff --git a/contribute.md b/contribute.md index 1abb5e539c..4a7d38faec 100644 --- a/contribute.md +++ b/contribute.md @@ -1,9 +1,9 @@ --- -layout: contribute -title: Contribute +layout: singlepage-overview +title: Why Contribute to docs.scala-lang.org? --- -###### Heather Miller +###### A note from Heather Miller ## A Place to Build Documentation Together @@ -21,175 +21,6 @@ If we want Scala to be accessible to more programmers, clear, easy-to-find docum If you're interested in contributing to the Scala project in general, I argue that one of the most meaningful ways that you can, is to help us improve this transfer of information- let's make it easier and faster for people to _get_ core concepts, and to answer their own questions so they can progress to _Scala-proficient_ quickly. Each line that you contribute has the potential to affect the entire Scala community as a whole-- current, and future. -## About docs.scala-lang.org +## How Can I Contribute? -### Content - -Currently, the _types_ of documentation supported in this repository are: - -- **Guides/Overviews**: Definitive guides/overviews of specific language features. Often long, detailed documents, often produced by members of the Scala team. An example is the excellent [Collections]({{ site.baseurl }}/overviews/collections-2.13/introduction.html) overview. -- **Tutorials**: Bite-size, example-rich, and concise articles meant to get a developer up to speed quickly. -- **Cheatsheets**: Quick reference of Scala syntax and behaviors. - -### Implementation - -This documentation repository is open-source, it lives in [github repository](https://github.com/scala/docs.scala-lang), and is always contribution-ready. - -It's statically generated from [Markdown](https://en.wikipedia.org/wiki/Markdown) source using [Jekyll](https://github.com/mojombo/jekyll), and hosted on [GitHub Pages](https://pages.github.com/). This workflow was chosen so as to make it as easy as possible for core committers and the community alike to produce HTML documentation, and as easy as possible to publish it in a central location. - -The markdown syntax being used supports [Maruku](https://github.com/bhollis/maruku) extensions, and has automatic syntax highlighting, without the need for any tags. - -Additionally [mdoc](https://github.com/scalameta/mdoc) is used during pull requests to validate Scala code blocks. To use this feature you must use the backtick notation as documented by mdoc. Note that only validation is done. The output files from mdoc are not used in the building of the tutorial. Use `mdoc` or `mdoc:fail` for your code blocks. - -## Submitting Docs - -For one to contribute a document, one must simply -[fork](https://help.github.com/articles/fork-a-repo/) the -[repo](https://github.com/scala/docs.scala-lang), write their article in -[Markdown](https://daringfireball.net/projects/markdown/syntax) (example below), and submit a pull request. That's it. Likely after some edits and discussion, your document will be made live on [docs.scala-lang.org](https://docs.scala-lang.org). - - --- - layout: overview - title: My Awesome Title - --- - - ## An h2 Header in Markdown - - And a paragraph, with a [link](https://www.scala-lang.org). - - One can contribute code by indenting it 4 spaces, or in-line by putting backticks around it like so, `def foo` - -Everything else is automatically generated for you; tables of contents, and most index pages. And of course, the styling is already taken care of for you. - -### Criteria for Docs to be Accepted - -The goal of this documentation repository is to be tighter and more organized than other community-driven documentation platforms, like wikis. As such, any document pulled in for inclusion on [https://docs.scala-lang.org](https://docs.scala-lang.org) must: - -- **"fit in"** to the repository ( _i.e.,_ it should not be a complete duplicate of another article), -- **be polished** it must be thorough, complete, correct, organized, and "article-like" (personal programming notes don't quite fit.) -- **be maintained** if the document might require revisions from time to time, it should come with an owner - -If you have something you're thinking about contributing, or that you're thinking about writing in order to contribute-- we'd love to consider it! Please don't hesitate to use GitHub issues and pull requests and the \#scala-contributors room [on Discord](https://discord.com/invite/scala) for any questions, concerns, clarifications, etc. - -## Document Templates - -
-

Note: These templates will soon change slightly as a result of necessary refactoring.

-
- -### Guides/Overviews - -A guide or an overview that can be logically placed on **one** page must be placed in the directory `overviews/RELEVANT-CATEGORY/_posts` with the file name in the format `YYYY-MM-dd-title-separated-by-dashes.md`, and header: - - --- - layout: overview - title: YOUR TITLE - --- - -The rest of the document should, of course, be written in [Markdown](https://en.wikipedia.org/wiki/Markdown). - -At the moment, `RELEVANT-CATEGORY` corresponds to only a single category, "core," because we are currently focusing on building up documentation of core libraries. However, expect more categories here in the future. - -If your document consists of **multiple** pages, like the [Collections]({{ site.baseurl }}/overviews/collections-2.13/introduction.html) overview, an ordering must be specified, by numbering documents in their logical order with `num`, and a name must be assigned to the collection of pages using `partof`. For example, the following header might be used for a document in the collections overview: - - --- - layout: overview - title: YOUR TITLE - - partof: collections - num: 10 - --- - -A **single** document in the collection must contain a tag in the header, `outof`, that indicates the total number of documents in the large overview. Putting it on the last page in the overview is often best: - - --- - layout: overview - title: YOUR TITLE - - partof: collections - num: 15 - outof: 15 - --- - -Index pages, such as [https://docs.scala-lang.org/overviews/index.html](https://docs.scala-lang.org/overviews/index.html) are automatically generated, assuming documents are properly placed under the correct `RELEVANT-CATEGORY`. So, simply drop your document into the correct folder, and you're done. - -### Tutorials - -At the moment, a tutorial that can be logically placed on **one** page must be placed in the directory `tutorials/` with the file name in the format `title-separated-by-dashes.md`. For the moment, single-page tutorials use the same layout as single-page overviews: - - --- - layout: overview - title: YOUR TITLE - --- - -If you have a **multiple-page** tutorial, like in the case of multiple-page overviews, you must both specify an ordering for your document, and a name must be assigned to the collection of tutorial pages. For example, the following header is used for the [Tour of Scala]({{ site.baseurl }}/tour/tour-of-scala.html) series of tutorial articles: - - --- - layout: inner-page-no-masthead - title: YOUR TITLE - - tutorial: scala-tour - num: 4 - --- - -At the moment, only indexes for multiple-page tutorials are automatically generated. - -### Cheatsheets - -For now, cheatsheets are assumed to be in the form of tables. To contribute a cheatsheet, one must simply produce their cheatsheet as a Markdown table, with the following header: - - --- - layout: cheatsheet - title: YOUR TITLE - by: YOUR NAME - about: SOME TEXT ABOUT THE CHEAT SHEET. - --- - -### Code blocks - -The site build process uses [mdoc](https://scalameta.org/mdoc/) to typecheck -code snippets in markdown. This is a great way to ensure the code snippets that -you're including typecheck and are valid. Here are a few quick types to get -started. - -To get started, you can simply add `mdoc` behind `scala` when you are creating a -code block. The `mdoc` modifier here will make sure that `mdoc` runs the code -snippet and ensures that it's valid. - - ```scala mdoc - val a = 1 - ``` -If you have a snippet that you expect to fail, you can also account for this by -using `mdoc:fail` for a compile error `mdoc:crash` for a runtime-error. - - ```scala mdoc:fail - val b: String = 3 // won't compile - ``` -Keep in mind that a single file is all compiled as a single unit, so you can't -redefine a variable that was defined above in another code snippet. _However_ -there are a couple ways to get around this. Firstly, you can use the `mdoc:nest` -modifier with will wrap the snippet in a `scala.Predef.locally{...}`. This will -essentially "hide" the snippet from the others. Another way around this is to -use the `mdoc:reset` modifier, which _resets_ and forgets about everything up -above. Here is an example using the various modifiers. - - ```scala mdoc - import java.time.Instant - - def now() = Instant.now() - object Foo {} - ``` - - ```scala mdoc:nest - case class Foo(a: Int) // conflicts with Foo above, but it's nested so it's fine - ``` - - ```scala mdoc - val a = s"The time is ${now()}" // still have access to the now method from above - ``` - ```scala mdoc:reset - case class Foo(a: String) // forget the previous Foo's and start fresh - ``` - ```scala mdoc - val myFoo = Foo("hi") // now we only have access to the last Foo - ``` +Please read: [Add New Guides/Tutorials](/overviews/contribute/add-guides.html) From 4b34e7fa4a4a5a972026e91cc3daa76451f3489d Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Mon, 21 Mar 2022 15:19:19 +0100 Subject: [PATCH 1805/3075] integrate guide with the site --- _data/doc-nav-header.yml | 2 ++ _data/nav-header.yml | 7 ++++++- _includes/site-header.html | 2 +- _ja/scala3/contribute-to-docs.md | 4 ++-- _ja/scala3/new-in-scala3.md | 2 +- index.md | 6 +++++- scala3/contribute-to-docs.md | 4 ++-- scala3/guides.md | 2 +- scala3/index.md | 2 +- scala3/new-in-scala3.md | 2 +- 10 files changed, 22 insertions(+), 11 deletions(-) diff --git a/_data/doc-nav-header.yml b/_data/doc-nav-header.yml index a96fdb3d42..9f45227579 100644 --- a/_data/doc-nav-header.yml +++ b/_data/doc-nav-header.yml @@ -35,6 +35,8 @@ url: "/tutorials/FAQ/index.html" - title: Language Specification url: http://scala-lang.org/files/archive/spec/2.13/ + - title: Contribution Guide + url: "/overviews/contribute/" - title: Style Guide url: "/style/index.html" - title: Cheatsheet diff --git a/_data/nav-header.yml b/_data/nav-header.yml index 26bd280020..a9d2f9ab38 100644 --- a/_data/nav-header.yml +++ b/_data/nav-header.yml @@ -1,12 +1,17 @@ - title: Documentation url: "/" + can-highlight: true - title: Download url: https://www.scala-lang.org/download/ + can-highlight: true - title: Community url: https://www.scala-lang.org/community/ + can-highlight: true - title: Libraries url: https://index.scala-lang.org + can-highlight: true - title: Contribute - url: https://www.scala-lang.org/contribute/ + url: /overviews/contribute/ - title: Blog url: https://www.scala-lang.org/blog/ + can-highlight: true diff --git a/_includes/site-header.html b/_includes/site-header.html index 31f2bc2a38..70f1cb6840 100644 --- a/_includes/site-header.html +++ b/_includes/site-header.html @@ -10,7 +10,7 @@ diff --git a/_ja/scala3/contribute-to-docs.md b/_ja/scala3/contribute-to-docs.md index 2902ff1d2a..c13b4b0904 100644 --- a/_ja/scala3/contribute-to-docs.md +++ b/_ja/scala3/contribute-to-docs.md @@ -45,8 +45,8 @@ Scala 3 の高品質なドキュメンテーションを作るためのいくつ - [Source](https://github.com/scala/docs.scala-lang/tree/main/_overviews/scala3-migration) - [Issues](https://github.com/scalacenter/docs.scala-lang/issues) -## Scala 3 Contribution Guide -[Scala 3 Contribution Guide](/scala3/guides/contribution/contribution-intro.html) +## Scala 3 Contributing Guide +[Scala 3 Contributing Guide](/scala3/guides/contribution/contribution-intro.html) Scala 3 コンパイラとライブラリへの貢献と内部に関する包括的な概要が含まれています - [Source](https://github.com/scala/docs.scala-lang/tree/main/_overviews/scala3-contribution) diff --git a/_ja/scala3/new-in-scala3.md b/_ja/scala3/new-in-scala3.md index eea8ee14ca..8e69859268 100644 --- a/_ja/scala3/new-in-scala3.md +++ b/_ja/scala3/new-in-scala3.md @@ -13,7 +13,7 @@ Scala 3 は Scala 2 から大幅な改善が行われ、さまざまな新機能 - [Syntax Summary][syntax-summary] では Scala 3 で新しく追加されたシンタックスを解説している。 - [Language Reference][reference] を見ればScala 2 と Scala 3 の変更点を詳しく確認できる。 - Scala 2 から Scala 3 への移行を考えている方は[Migration Guide][migration] を参照。 -- [Contribution Guide][contribution] は、問題を修正するためのガイドを含め、コンパイラーをさらに深く掘り下げます。 +- [Scala 3 Contributing Guide][contribution] は、問題を修正するためのガイドを含め、コンパイラーをさらに深く掘り下げます。 ## What's new in Scala 3 Scala 3 は Scala 2 を徹底的に見直して再設計されている。核心部分で、型システムの多くの面が変更されより原理原則に基づいたものになった。この変更によって新機能(ユニオン型)が使えるようになったことにくわえて、なにより型システムがさらに使いやすくなった。 例えば、[型推論][type-inference] や overload resolution が改善された. diff --git a/index.md b/index.md index 7e778ec83c..aacc00e221 100644 --- a/index.md +++ b/index.md @@ -40,7 +40,7 @@ scala3-sections: description: "The Scala 3 language reference." icon: "fa fa-book" link: /scala3/reference/overview.html - - title: "Contribution Guide" + - title: "Scala 3 Contributing Guide" description: "Guide to the Scala 3 Compiler and fixing an issue" icon: "fa fa-cogs" link: /scala3/guides/contribution/contribution-intro.html @@ -118,4 +118,8 @@ scala2-sections: description: "The Scala Improvement Process. Language & compiler evolution." icon: "fa fa-cogs" link: /sips/index.html + - title: "Contributing to Scala" + description: "The Complete Guide to Contributing to the Scala Project" + icon: "fa fa-cogs" + link: /overviews/contribute/ --- diff --git a/scala3/contribute-to-docs.md b/scala3/contribute-to-docs.md index 5a2a336440..d39ba71ec4 100644 --- a/scala3/contribute-to-docs.md +++ b/scala3/contribute-to-docs.md @@ -45,8 +45,8 @@ a tour presenting the migration tools, and detailed migration guides. - [Source](https://github.com/scala/docs.scala-lang/tree/main/_overviews/scala3-migration) - [Issues](https://github.com/scala/docs.scala-lang/issues) -## Scala 3 Contribution Guide -The [Scala 3 Contribution Guide](/scala3/guides/contribution/contribution-intro.html) +## Scala 3 Contributing Guide +The [Scala 3 Contributing Guide](/scala3/guides/contribution/contribution-intro.html) contains a comprehensive overview over contribution to and internals of the Scala 3 compiler and libraries - [Source](https://github.com/scala/docs.scala-lang/tree/main/_overviews/scala3-contribution) diff --git a/scala3/guides.md b/scala3/guides.md index 812cedb611..26110b10ba 100644 --- a/scala3/guides.md +++ b/scala3/guides.md @@ -18,7 +18,7 @@ guides: icon: birthday-cake url: "/scala3/guides/tasty-overview.html" description: "An overview over the TASTy format aimed at end-users of the Scala language." - - title: "Contribution Guide" + - title: "Scala 3 Contributing Guide" by: Jamie Thompson, Anatolii Kmetiuk icon: cogs url: "/scala3/guides/contribution/contribution-intro.html" diff --git a/scala3/index.md b/scala3/index.md index 7c741fd931..a34c19a1ca 100644 --- a/scala3/index.md +++ b/scala3/index.md @@ -40,7 +40,7 @@ sections: description: "The Scala 3 language reference." icon: "fa fa-book" link: /scala3/reference/overview.html - - title: "Contribution Guide" + - title: "Scala 3 Contributing Guide" description: "Guide to the Scala 3 Compiler and fixing an issue" icon: "fa fa-cogs" link: /scala3/guides/contribution/contribution-intro.html diff --git a/scala3/new-in-scala3.md b/scala3/new-in-scala3.md index 9a1e9da872..af6d6111c1 100644 --- a/scala3/new-in-scala3.md +++ b/scala3/new-in-scala3.md @@ -11,7 +11,7 @@ changes. If you want to dig deeper, there are a few references at your disposal: - The [Syntax Summary][syntax-summary] provides you with a formal description of the new syntax. - The [Language Reference][reference] gives a detailed description of the changes from Scala 2 to Scala 3. - The [Migration Guide][migration] provides you with all of the information necessary to move from Scala 2 to Scala 3. -- The [Contribution Guide][contribution] dives deeper into the compiler, including a guide to fix issues. +- The [Scala 3 Contributing Guide][contribution] dives deeper into the compiler, including a guide to fix issues. ## What's new in Scala 3 Scala 3 is a complete overhaul of the Scala language. At its core, many aspects From aa00e9cd6626ada8738267b9fb8a50f5378dfe0c Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Mon, 21 Mar 2022 12:17:23 -0500 Subject: [PATCH 1806/3075] update status of JDK 8 also change AdoptOpenJDK->Temurin also move some GraalVM text to a more appropriate location --- _overviews/jdk-compatibility/overview.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/_overviews/jdk-compatibility/overview.md b/_overviews/jdk-compatibility/overview.md index 9eb850a77f..c00fd2f05f 100644 --- a/_overviews/jdk-compatibility/overview.md +++ b/_overviews/jdk-compatibility/overview.md @@ -26,13 +26,11 @@ Lightbend offers [commercial support](https://www.lightbend.com/lightbend-platfo ## Running versus compiling -JDK 8, 11, and 17 are all good choices both for *compiling* and *running* Scala code. +JDK 8, 11, and 17 are all reasonable choices both for *compiling* and *running* Scala code. Since the JVM is normally backwards compatible, it is usually safe to use a newer JVM for *running* your code than the one it was compiled on, especially if you are not using JVM features designated "experimental" or "unsafe". -If you compile on JDK 11+ but have users on an older JDK version, additional care is needed to avoid using APIs and features that don't exist in 8. Therefore, *compiling* on 8 may be the safest choice in this scenario. (Some Scala developers use JDK 11 or 17 for their daily work, but do release builds on JDK 8.) - -Additionally, you can also run your Scala application on GraalVM which is a JVM. GraalVM performs well on the Scala benchmarks, and it benefits from GraalVM runtime and runs faster too. +JDK 8 remains in use at many shops (as of early 2022), but usage is declining and some projects are dropping support. If you compile on JDK 11+ but want to allow your users to stay on 8, additional care is needed to avoid using APIs and features that don't exist in 8. (For this reason, some Scala developers use JDK 11 or 17 for their daily work but do release builds on JDK 8.) ## Long Term Support (LTS) versions @@ -50,9 +48,9 @@ In almost every case, you're free to use the JDK and JVM of your choice. JDK 8 users typically use the Oracle JDK or some flavor of OpenJDK. -Most JDK 11+ users are using either OpenJDK or GraalVM which runs in the context of OpenJDK. +Most JDK 11+ users are using OpenJDK, or GraalVM which runs in the context of OpenJDK. GraalVM performs well on the Scala benchmarks, and it benefits from GraalVM runtime and runs faster too. -OpenJDK comes in various flavors, offered by different providers. We build and test Scala using [AdoptOpenJDK](https://adoptopenjdk.net) in particular, but the differences are unlikely to matter to most users. +OpenJDK comes in various flavors, offered by different providers. We build and test Scala using [Temurin](https://adoptium.net) primarily, but the differences are unlikely to matter to most users. ## JDK 11 compatibility notes From 302bfbff1dc497bd07acaf9c5596ec94f8d50aa0 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Tue, 22 Mar 2022 16:00:44 +0100 Subject: [PATCH 1807/3075] revert to /contribute/ urls --- README.md | 2 +- _config.yml | 8 +++++ _contribute_resources/1-documentation.md | 4 +-- _contribute_resources/2-bug-fixes.md | 4 +-- _contribute_resources/3-code-reviews.md | 2 +- _contribute_resources/4-core-libraries.md | 2 +- .../5-ide-and-build-tools.md | 2 +- _contribute_resources/6-compiler-language.md | 2 +- _data/doc-nav-header.yml | 2 +- _data/nav-header.yml | 2 +- _overviews/contribute/add-guides.md | 3 -- _overviews/contribute/bug-reporting-guide.md | 3 -- _overviews/contribute/codereviews.md | 7 ++--- _overviews/contribute/corelibs.md | 9 ++---- _overviews/contribute/documentation.md | 13 +++----- _overviews/contribute/guide.md | 31 +++++++++---------- _overviews/contribute/hacker-guide.md | 5 +-- .../contribute/inclusive-language-guide.md | 3 -- _overviews/contribute/index.md | 7 ++--- _overviews/contribute/partest-guide.md | 3 -- _overviews/contribute/scala-internals.md | 3 -- ...cala-standard-library-api-documentation.md | 7 ++--- _overviews/contribute/tools.md | 7 ++--- contribute.md | 2 +- index.md | 2 +- 25 files changed, 52 insertions(+), 83 deletions(-) diff --git a/README.md b/README.md index ee37fe58d4..fe377e9f6b 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ For more details on the Docker option, see [this issue](https://github.com/scala ## Contributing ## -Please have a look at [Add New Guides/Tutorials](https://docs.scala-lang.org/overviews/contribute/add-guides.html) before making a contribution. +Please have a look at [Add New Guides/Tutorials](https://docs.scala-lang.org/contribute/add-guides.html) before making a contribution. This document gives an overview of the type of documentation contained within the Scala Documentation repository and the repository's structure. Small changes, or corrected typos will generally be pulled in right away. Large changes, like the addition of new documents, or the rewriting of diff --git a/_config.yml b/_config.yml index 0d58e58a8f..43f6dfd536 100644 --- a/_config.yml +++ b/_config.yml @@ -105,6 +105,14 @@ defaults: overview-name: "Scala 3 — Book" layout: multipage-overview permalink: "/scala3/book/:title.html" + - + scope: + path: "_overviews/contribute" + values: + partof: scala-contribution + overview-name: Contributing to Scala + layout: multipage-overview + permalink: "/contribute/:title.html" - scope: path: "_overviews/scala3-migration" diff --git a/_contribute_resources/1-documentation.md b/_contribute_resources/1-documentation.md index 7515ff7519..474bea075f 100644 --- a/_contribute_resources/1-documentation.md +++ b/_contribute_resources/1-documentation.md @@ -1,6 +1,6 @@ --- title: Documentation -link: /overviews/contribute/documentation.html +link: /contribute/documentation.html icon: fa fa-book --- -[Scaladoc (API)](/overviews/contribute/scala-standard-library-api-documentation.html), [docs.scala-lang.org](/overviews/contribute/add-guides.html) and [scala-lang.org](https://github.com/scala/scala-lang). +[Scaladoc (API)](/contribute/scala-standard-library-api-documentation.html), [docs.scala-lang.org](/contribute/add-guides.html) and [scala-lang.org](https://github.com/scala/scala-lang). diff --git a/_contribute_resources/2-bug-fixes.md b/_contribute_resources/2-bug-fixes.md index 2baf672e5a..54e6d2cf9d 100644 --- a/_contribute_resources/2-bug-fixes.md +++ b/_contribute_resources/2-bug-fixes.md @@ -1,6 +1,6 @@ --- title: Bug fixes -link: /overviews/contribute/guide.html +link: /contribute/guide.html icon: fa fa-bug --- -Issues with the tools, core libraries and compiler. Also you can help us by [reporting bugs](/overviews/contribute/bug-reporting-guide.html). +Issues with the tools, core libraries and compiler. Also you can help us by [reporting bugs](/contribute/bug-reporting-guide.html). diff --git a/_contribute_resources/3-code-reviews.md b/_contribute_resources/3-code-reviews.md index e6f15e271c..e03305beb5 100644 --- a/_contribute_resources/3-code-reviews.md +++ b/_contribute_resources/3-code-reviews.md @@ -1,6 +1,6 @@ --- title: Code Reviews -link: /overviews/contribute/codereviews.html +link: /contribute/codereviews.html icon: fa fa-eye --- Review pull requests against [scala/scala](https://github.com/scala/scala/pulls), diff --git a/_contribute_resources/4-core-libraries.md b/_contribute_resources/4-core-libraries.md index fb66a906b8..06f1018479 100644 --- a/_contribute_resources/4-core-libraries.md +++ b/_contribute_resources/4-core-libraries.md @@ -1,6 +1,6 @@ --- title: Core Libraries -link: /overviews/contribute/corelibs.html +link: /contribute/corelibs.html icon: fa fa-clipboard --- Update and expand the capabilities of the core (and associated) Scala libraries. diff --git a/_contribute_resources/5-ide-and-build-tools.md b/_contribute_resources/5-ide-and-build-tools.md index 2bf2c7d729..7202f0d953 100644 --- a/_contribute_resources/5-ide-and-build-tools.md +++ b/_contribute_resources/5-ide-and-build-tools.md @@ -1,6 +1,6 @@ --- title: IDE and Build Tools -link: /overviews/contribute/tools.html +link: /contribute/tools.html icon: fa fa-terminal --- Enhance the Scala tools with features for build tools, IDE plug-ins and other related projects. diff --git a/_contribute_resources/6-compiler-language.md b/_contribute_resources/6-compiler-language.md index a7dc618322..d54e34fac9 100644 --- a/_contribute_resources/6-compiler-language.md +++ b/_contribute_resources/6-compiler-language.md @@ -1,6 +1,6 @@ --- title: Compiler/Language -link: /overviews/contribute/guide.html#larger-changes-new-features +link: /contribute/guide.html#larger-changes-new-features icon: fa fa-cogs --- Larger language features and compiler enhancements including language specification and SIPs. diff --git a/_data/doc-nav-header.yml b/_data/doc-nav-header.yml index 9f45227579..52b66be1da 100644 --- a/_data/doc-nav-header.yml +++ b/_data/doc-nav-header.yml @@ -36,7 +36,7 @@ - title: Language Specification url: http://scala-lang.org/files/archive/spec/2.13/ - title: Contribution Guide - url: "/overviews/contribute/" + url: "/contribute/" - title: Style Guide url: "/style/index.html" - title: Cheatsheet diff --git a/_data/nav-header.yml b/_data/nav-header.yml index a9d2f9ab38..03621e6d64 100644 --- a/_data/nav-header.yml +++ b/_data/nav-header.yml @@ -11,7 +11,7 @@ url: https://index.scala-lang.org can-highlight: true - title: Contribute - url: /overviews/contribute/ + url: /contribute/ - title: Blog url: https://www.scala-lang.org/blog/ can-highlight: true diff --git a/_overviews/contribute/add-guides.md b/_overviews/contribute/add-guides.md index c8f5e42f0c..8e638021d2 100644 --- a/_overviews/contribute/add-guides.md +++ b/_overviews/contribute/add-guides.md @@ -1,9 +1,6 @@ --- title: Add New Guides/Tutorials -layout: multipage-overview num: 7 -partof: scala-contribution -overview-name: Contributing to Scala --- ## Why Contribute New Learning Material? diff --git a/_overviews/contribute/bug-reporting-guide.md b/_overviews/contribute/bug-reporting-guide.md index ac6df525a5..e2637ccd09 100644 --- a/_overviews/contribute/bug-reporting-guide.md +++ b/_overviews/contribute/bug-reporting-guide.md @@ -1,9 +1,6 @@ --- title: Bug Reporting Guide -layout: multipage-overview num: 8 -partof: scala-contribution -overview-name: Contributing to Scala --- The Scala compiler and standard library bug tracker is located at [https://github.com/scala/bug](https://github.com/scala/bug), and for Scala 3, it is located at [github.com/lampepfl/dotty](https://github.com/lampepfl/dotty/issues). Before you submit a bug make sure that it is certainly a bug by following instructions in *Is it a Bug?*. diff --git a/_overviews/contribute/codereviews.md b/_overviews/contribute/codereviews.md index e7dea2acea..6325fcde6c 100644 --- a/_overviews/contribute/codereviews.md +++ b/_overviews/contribute/codereviews.md @@ -1,13 +1,10 @@ --- title: Code Review Contributions -layout: multipage-overview num: 3 -partof: scala-contribution -overview-name: Contributing to Scala --- ## Code Review Contributions -In addition to [bug fixing](/overviews/contribute/guide.html), you can help us review +In addition to [bug fixing](/contribute/guide.html), you can help us review [waiting pull requests](#pull-requests-awaiting-comment). This is also a good (and recommended) way to get to know the feel of the bug-fixing and submissions process before jumping in with your @@ -57,4 +54,4 @@ own pull requests. -Also note that the [Tools contributions](/overviews/contribute/tools.html) page has more projects that will generate pull requests. +Also note that the [Tools contributions](/contribute/tools.html) page has more projects that will generate pull requests. diff --git a/_overviews/contribute/corelibs.md b/_overviews/contribute/corelibs.md index 6c64a887d7..3ee05e6c13 100644 --- a/_overviews/contribute/corelibs.md +++ b/_overviews/contribute/corelibs.md @@ -1,17 +1,14 @@ --- title: Core Library Contributions -layout: multipage-overview num: 4 -partof: scala-contribution -overview-name: Contributing to Scala --- ## Core Library Contributions There are several options for contributing to Scala's core libraries. You can: -* Help with [Documentation](/overviews/contribute/documentation.html). -* [Report Bugs or Issues](/overviews/contribute/bug-reporting-guide.html) against the core libraries. -* [Fix Bugs or Issues](/overviews/contribute/guide.html) against the +* Help with [Documentation](/contribute/documentation.html). +* [Report Bugs or Issues](/contribute/bug-reporting-guide.html) against the core libraries. +* [Fix Bugs or Issues](/contribute/guide.html) against the [reported library bugs/issues](https://github.com/scala/bug). ### Significant changes diff --git a/_overviews/contribute/documentation.md b/_overviews/contribute/documentation.md index 417f9b234a..3d3311dbce 100644 --- a/_overviews/contribute/documentation.md +++ b/_overviews/contribute/documentation.md @@ -1,9 +1,6 @@ --- title: Documentation Contributions -layout: multipage-overview num: 5 -partof: scala-contribution -overview-name: Contributing to Scala --- ## Contributing Documentation to the Scala project @@ -23,11 +20,11 @@ Thanks The Scala API documentation lives with the scala project source code. There are many ways you can help with improving Scaladoc, including: -* [Log issues for missing scaladoc documentation](/overviews/contribute/scala-standard-library-api-documentation.html#contribute-api-documentation-bug-reports) - +* [Log issues for missing scaladoc documentation](/contribute/scala-standard-library-api-documentation.html#contribute-api-documentation-bug-reports) - Please *follow the issue submission process closely* to help prevent duplicate issues being created. -* [Claim Scaladoc Issues and Provide Documentation](/overviews/contribute/scala-standard-library-api-documentation.html) - please claim issues prior to working on a specific scaladoc task to prevent duplication of effort. If you sit on an issue for too long without submitting a pull request, it will revert back to unassigned and you will need to re-claim it. +* [Claim Scaladoc Issues and Provide Documentation](/contribute/scala-standard-library-api-documentation.html) - please claim issues prior to working on a specific scaladoc task to prevent duplication of effort. If you sit on an issue for too long without submitting a pull request, it will revert back to unassigned and you will need to re-claim it. * You can also just -[submit new Scaladoc](/overviews/contribute/scala-standard-library-api-documentation.html) +[submit new Scaladoc](/contribute/scala-standard-library-api-documentation.html) without creating an issue, but please look to see if there is an issue already submitted for your task and claim it if there is. If not, please post your intention to work on a specific scaladoc task on [Scala Contributors](https://contributors.scala-lang.org/) so that people know what you are doing. ### The Main Scala Documentation Site @@ -44,7 +41,7 @@ without creating an issue, but please look to see if there is an issue already s * SIP (Scala Improvement Process) Proposals and more -Please read [Add New Guides/Tutorials](/overviews/contribute/add-guides.html) through before embarking on changes. The site uses +Please read [Add New Guides/Tutorials](/contribute/add-guides.html) through before embarking on changes. The site uses the [Jekyll](https://jekyllrb.com/) markdown engine so you will need to follow the instructions to get that running as well. ### Updating scala-lang.org @@ -55,4 +52,4 @@ to Scala and related projects) is provided on the main [scala-lang GitHub project](https://github.com/scala/scala-lang) which may be forked to create pull requests. Please read both the -[Add New Guides/Tutorials](/overviews/contribute/add-guides.html) document and the [scala-lang.org GitHub README](https://github.com/scala/scala-lang#scala-langorg) before embarking on any changes to the Scala language site, as it uses the same Jekyll markdown tool and many of the same conventions as the Scala documentation site. +[Add New Guides/Tutorials](/contribute/add-guides.html) document and the [scala-lang.org GitHub README](https://github.com/scala/scala-lang#scala-langorg) before embarking on any changes to the Scala language site, as it uses the same Jekyll markdown tool and many of the same conventions as the Scala documentation site. diff --git a/_overviews/contribute/guide.md b/_overviews/contribute/guide.md index 802e3c387c..70d470d454 100644 --- a/_overviews/contribute/guide.md +++ b/_overviews/contribute/guide.md @@ -1,9 +1,6 @@ --- title: Contributing guide -layout: multipage-overview num: 10 -partof: scala-contribution -overview-name: Contributing to Scala --- | **Shortcut** | **Description** | @@ -41,19 +38,19 @@ unencumbered by copyrights or patents. This is the impatient developer's checklist for the steps to submit a bug-fix pull request to the Scala project. For more information, description and justification for the steps, follow the links in that step. Further specific instructions for the release of Scala you are targeting can be found in the `CONTRIBUTING.md` file for that [GitHub branch](https://github.com/scala/scala) -1. [Select a bug to fix from GitHub](/overviews/contribute/index.html#community-tickets), or if you found the bug yourself and want to fix it, [create a GitHub issue](/overviews/contribute/bug-reporting-guide.html) (but please -[make sure it's not a duplicate](/overviews/contribute/bug-reporting-guide.html#please-check-before-reporting-a-bug)). -2. Optional ([but recommended](/overviews/contribute/scala-internals.html/#why-its-a-good-idea)), announce your intention to work on the bug on [Scala Contributors](https://contributors.scala-lang.org/). After all, don't you want to work on a team with -[these friendly people](/overviews/contribute/hacker-guide.html#1-connect) - it's one of the perks of contributing. -3. [Fork the Scala repository](/overviews/contribute/hacker-guide.html#fork) and clone your fork (if you haven't already). -4. [Create a feature branch](/overviews/contribute/hacker-guide.html#branch) to work on: use the branch name `issue/NNNN` where NNNN is the GitHub issue number. -5. [Fix the bug, or implement the new small feature](/overviews/contribute/hacker-guide.html#implement), include new tests (yes, for bug fixes too). -6. [Test, rinse](/overviews/contribute/hacker-guide.html#test) and [test some more](/overviews/contribute/partest-guide.html) until [all the tests pass](/overviews/contribute/hacker-guide.html#verify). -7. [Commit your changes](/overviews/contribute/hacker-guide.html#commit) to your feature branch in your fork. Please choose your commit message based on the [Git Hygiene](https://github.com/scala/scala#user-content-git-hygiene) section of the Scala project README. +1. [Select a bug to fix from GitHub](/contribute/index.html#community-tickets), or if you found the bug yourself and want to fix it, [create a GitHub issue](/contribute/bug-reporting-guide.html) (but please +[make sure it's not a duplicate](/contribute/bug-reporting-guide.html#please-check-before-reporting-a-bug)). +2. Optional ([but recommended](/contribute/scala-internals.html/#why-its-a-good-idea)), announce your intention to work on the bug on [Scala Contributors](https://contributors.scala-lang.org/). After all, don't you want to work on a team with +[these friendly people](/contribute/hacker-guide.html#1-connect) - it's one of the perks of contributing. +3. [Fork the Scala repository](/contribute/hacker-guide.html#fork) and clone your fork (if you haven't already). +4. [Create a feature branch](/contribute/hacker-guide.html#branch) to work on: use the branch name `issue/NNNN` where NNNN is the GitHub issue number. +5. [Fix the bug, or implement the new small feature](/contribute/hacker-guide.html#implement), include new tests (yes, for bug fixes too). +6. [Test, rinse](/contribute/hacker-guide.html#test) and [test some more](/contribute/partest-guide.html) until [all the tests pass](/contribute/hacker-guide.html#verify). +7. [Commit your changes](/contribute/hacker-guide.html#commit) to your feature branch in your fork. Please choose your commit message based on the [Git Hygiene](https://github.com/scala/scala#user-content-git-hygiene) section of the Scala project README. 8. If necessary [re-write git history](https://git-scm.com/book/en/Git-Branching-Rebasing) so that [commits are organized by major steps to the fix/feature]( https://github.com/scala/scala#git-hygiene). For bug fixes, a single commit is requested, for features several commits may be desirable (but each separate commit must compile and pass all tests) -9. [Submit a pull request](/overviews/contribute/hacker-guide.html#submit). -10. [Work with a reviewer](https://github.com/scala/scala#reviewing) to [get your pull request merged in](/overviews/contribute/hacker-guide.html#review). +9. [Submit a pull request](/contribute/hacker-guide.html#submit). +10. [Work with a reviewer](https://github.com/scala/scala#reviewing) to [get your pull request merged in](/contribute/hacker-guide.html#review). 11. Celebrate! Need more information or a little more hand-holding for the first one? We got you covered: take a read through the entire [Hacker Guide][hackers] (or the [equivalent Scala 3 Contributing Guide][scala3-hackers]) for an example of implementing a new feature (some of the steps can be skipped for bug fixes, this will be obvious from reading it, but many of the steps here will help with bug fixes too). @@ -67,8 +64,8 @@ on the [Scala Contributors](https://contributors.scala-lang.org/) mailing list a Contributions, big or small, simple or complex, controversial or undisputed, need to materialize as patches against the Scala project source tree. The hacker's guides ([Scala 2][hackers], or [Scala 3][scala3-hackers]) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. -[hackers]: /overviews/contribute/hacker-guide.html -[community-tickets]: /overviews/contribute/index.html#community-tickets -[bug-reporting-guide]: /overviews/contribute/bug-reporting-guide.html +[hackers]: /contribute/hacker-guide.html +[community-tickets]: /contribute/index.html#community-tickets +[bug-reporting-guide]: /contribute/bug-reporting-guide.html [scala3-hackers]: {% link _overviews/scala3-contribution/procedures-intro.md %} [contrib-forum]: https://contributors.scala-lang.org/ diff --git a/_overviews/contribute/hacker-guide.md b/_overviews/contribute/hacker-guide.md index f342c98040..f9db614056 100644 --- a/_overviews/contribute/hacker-guide.md +++ b/_overviews/contribute/hacker-guide.md @@ -1,10 +1,7 @@ --- title: Scala hacker guide by: Eugene Burmako -layout: multipage-overview num: 12 -partof: scala-contribution -overview-name: Contributing to Scala ---
This guide is intended to help you get from an idea of fixing a bug or implementing a new feature into a nightly Scala build, and, ultimately, to a production release of Scala incorporating your idea. @@ -310,7 +307,7 @@ This means your change is backward or forward binary incompatible with the speci ### Verify -Now to make sure that my fix doesn't break anything I need to run the test suite. The Scala test suite uses [JUnit](https://junit.org/junit4/) and [partest](/overviews/contribute/partest-guide.html), a tool we wrote for testing Scala. +Now to make sure that my fix doesn't break anything I need to run the test suite. The Scala test suite uses [JUnit](https://junit.org/junit4/) and [partest](/contribute/partest-guide.html), a tool we wrote for testing Scala. Run `sbt test` and `sbt partest` to run all of the JUnit and partest tests, respectively. `partest` (not `sbt partest`) also allows you to run a subset of the tests using wildcards: diff --git a/_overviews/contribute/inclusive-language-guide.md b/_overviews/contribute/inclusive-language-guide.md index 7f7c428f42..375d988158 100644 --- a/_overviews/contribute/inclusive-language-guide.md +++ b/_overviews/contribute/inclusive-language-guide.md @@ -1,9 +1,6 @@ --- title: Inclusive Language Guide -layout: multipage-overview num: 2 -partof: scala-contribution -overview-name: Contributing to Scala --- We are committed to providing a friendly, safe and welcoming environment for diff --git a/_overviews/contribute/index.md b/_overviews/contribute/index.md index b89f04803a..eb0596d802 100644 --- a/_overviews/contribute/index.md +++ b/_overviews/contribute/index.md @@ -1,9 +1,6 @@ --- title: Contribute -layout: multipage-overview num: 1 -partof: scala-contribution -overview-name: Contributing to Scala --- The Scala programming language is an open source project with a very @@ -18,7 +15,7 @@ That depends on what you want to contribute. Below are some getting started reso ### Reporting bugs -See our [bug reporting guide](/overviews/contribute/bug-reporting-guide.html) to learn +See our [bug reporting guide](/contribute/bug-reporting-guide.html) to learn how to efficiently report a bug. ### Contribute @@ -33,7 +30,7 @@ Coordination of contribution efforts takes place on When contributing, please follow: * The [Scala Code of Conduct](https://scala-lang.org/conduct/) -* The [Inclusive Language Guide](/overviews/contribute/inclusive-language-guide.html) +* The [Inclusive Language Guide](/contribute/inclusive-language-guide.html) ### Community Tickets diff --git a/_overviews/contribute/partest-guide.md b/_overviews/contribute/partest-guide.md index 548eb8d5e6..c3e6980b06 100644 --- a/_overviews/contribute/partest-guide.md +++ b/_overviews/contribute/partest-guide.md @@ -1,9 +1,6 @@ --- title: Running the Test Suite -layout: multipage-overview num: 13 -partof: scala-contribution -overview-name: Contributing to Scala --- Partest is a custom parallel testing tool that we use to run the test suite for the Scala compiler and library. Go to the scala project folder from your local checkout and run it via `sbt`, `ant` or standalone as follows. diff --git a/_overviews/contribute/scala-internals.md b/_overviews/contribute/scala-internals.md index 5f391947fa..f3b1de54de 100644 --- a/_overviews/contribute/scala-internals.md +++ b/_overviews/contribute/scala-internals.md @@ -1,9 +1,6 @@ --- title: Scala Contributors Forum -layout: multipage-overview num: 9 -partof: scala-contribution -overview-name: Contributing to Scala --- The [Scala Contributors Forum][scala-contributors] is where discussions about the Scala ecosystem diff --git a/_overviews/contribute/scala-standard-library-api-documentation.md b/_overviews/contribute/scala-standard-library-api-documentation.md index 99f1bb16e0..606407f886 100644 --- a/_overviews/contribute/scala-standard-library-api-documentation.md +++ b/_overviews/contribute/scala-standard-library-api-documentation.md @@ -1,9 +1,6 @@ --- title: Contribute to API Documentation -layout: multipage-overview num: 6 -partof: scala-contribution -overview-name: Contributing to Scala --- This page is specific to API documentation contributions – that is, API @@ -13,7 +10,7 @@ sometimes referred to as Scaladoc contributions. For contributions to tutorial and guide-style documentation on [docs.scala-lang.org](/), -see [Add New Guides/Tutorials](/overviews/contribute/add-guides.html). +see [Add New Guides/Tutorials](/contribute/add-guides.html). *Please note, these instructions cover documentation contributions Scala core libraries only. For other Scala projects please check those projects for the @@ -79,7 +76,7 @@ component so that they show up in the correct issue filters. Please familiarize yourself with the following before contributing new API documentation to save time, effort, mistakes and repetition. -* [Forking the Repo](/overviews/contribute/hacker-guide.html#2-set-up) - follow the setup steps through +* [Forking the Repo](/contribute/hacker-guide.html#2-set-up) - follow the setup steps through the Branch section. If providing new documentation related to an existing GitHub issue, use `issue/NNNN` or `ticket/NNNN` as the guide states. If providing API documentation with no associated GitHub issue, use `scaladoc/xxxx` instead. diff --git a/_overviews/contribute/tools.md b/_overviews/contribute/tools.md index 875160ca96..68cee7796f 100644 --- a/_overviews/contribute/tools.md +++ b/_overviews/contribute/tools.md @@ -1,9 +1,6 @@ --- title: IDE and Build Tool Contributions -layout: multipage-overview num: 11 -partof: scala-contribution -overview-name: Contributing to Scala # Projects list: projects: @@ -22,7 +19,7 @@ projects: homeLink: https://www.scala-lang.org/api issuesLink: https://github.com/scala/bug/labels/scaladoc readmeLink: https://github.com/scala/scala#welcome - contributingLink: /overviews/contribute/guide.html + contributingLink: /contribute/guide.html - title: Partest description: Scala Compiler/Library Testing (Contribute through scala/scala) icon: https://avatars1.githubusercontent.com/u/57059?v=3&s=200 @@ -50,7 +47,7 @@ if you would like to help revive them. ### Broken Links? -Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](/overviews/contribute/documentation.html#updating-scala-langorg) to fix it. +Stuff changes. Found a broken link or something that needs updating on this page? Please, consider [submitting a documentation pull request](/contribute/documentation.html#updating-scala-langorg) to fix it. ### Projects diff --git a/contribute.md b/contribute.md index 4a7d38faec..02a8e4b8d7 100644 --- a/contribute.md +++ b/contribute.md @@ -23,4 +23,4 @@ If you're interested in contributing to the Scala project in general, I argue th ## How Can I Contribute? -Please read: [Add New Guides/Tutorials](/overviews/contribute/add-guides.html) +Please read: [Add New Guides/Tutorials](/contribute/add-guides.html) diff --git a/index.md b/index.md index aacc00e221..5790ce8b7c 100644 --- a/index.md +++ b/index.md @@ -121,5 +121,5 @@ scala2-sections: - title: "Contributing to Scala" description: "The Complete Guide to Contributing to the Scala Project" icon: "fa fa-cogs" - link: /overviews/contribute/ + link: /contribute/ --- From 573e494856dd4138c155d7e6dbb7492b2e21ad28 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Tue, 22 Mar 2022 16:59:40 +0100 Subject: [PATCH 1808/3075] use jekyll link tag to render internal links --- _contribute_resources/1-documentation.md | 5 ++- _contribute_resources/2-bug-fixes.md | 4 +- _includes/column-list-of-items.html | 2 +- _overviews/contribute/add-guides.md | 11 +++-- _overviews/contribute/bug-reporting-guide.md | 4 +- _overviews/contribute/codereviews.md | 7 ++- _overviews/contribute/corelibs.md | 10 +++-- _overviews/contribute/documentation.md | 17 +++++--- _overviews/contribute/guide.md | 43 ++++++++++++------- _overviews/contribute/hacker-guide.md | 12 ++++-- _overviews/contribute/index.md | 7 ++- ...cala-standard-library-api-documentation.md | 16 ++++--- 12 files changed, 94 insertions(+), 44 deletions(-) diff --git a/_contribute_resources/1-documentation.md b/_contribute_resources/1-documentation.md index 474bea075f..1f42a6e20b 100644 --- a/_contribute_resources/1-documentation.md +++ b/_contribute_resources/1-documentation.md @@ -3,4 +3,7 @@ title: Documentation link: /contribute/documentation.html icon: fa fa-book --- -[Scaladoc (API)](/contribute/scala-standard-library-api-documentation.html), [docs.scala-lang.org](/contribute/add-guides.html) and [scala-lang.org](https://github.com/scala/scala-lang). +[Scaladoc (API)][scala-standard-library-api-documentation], [docs.scala-lang.org][add-guides] and [scala-lang.org](https://github.com/scala/scala-lang). + +[add-guides]: {% link _overviews/contribute/add-guides.md %} +[scala-standard-library-api-documentation]: {% link _overviews/contribute/scala-standard-library-api-documentation.md %} diff --git a/_contribute_resources/2-bug-fixes.md b/_contribute_resources/2-bug-fixes.md index 54e6d2cf9d..7026e7e15b 100644 --- a/_contribute_resources/2-bug-fixes.md +++ b/_contribute_resources/2-bug-fixes.md @@ -3,4 +3,6 @@ title: Bug fixes link: /contribute/guide.html icon: fa fa-bug --- -Issues with the tools, core libraries and compiler. Also you can help us by [reporting bugs](/contribute/bug-reporting-guide.html). +Issues with the tools, core libraries and compiler. Also you can help us by [reporting bugs][bug-reporting-guide]. + +[bug-reporting-guide]: {% link _overviews/contribute/bug-reporting-guide.md %} diff --git a/_includes/column-list-of-items.html b/_includes/column-list-of-items.html index eb9e1600be..2ce303e678 100644 --- a/_includes/column-list-of-items.html +++ b/_includes/column-list-of-items.html @@ -15,4 +15,4 @@

{{item.title}}

{% endfor %} - \ No newline at end of file + diff --git a/_overviews/contribute/add-guides.md b/_overviews/contribute/add-guides.md index 8e638021d2..96091fb311 100644 --- a/_overviews/contribute/add-guides.md +++ b/_overviews/contribute/add-guides.md @@ -5,7 +5,7 @@ num: 7 ## Why Contribute New Learning Material? -As [Heather Miller writes](/contribute.html), contributing to [docs.scala-lang.org](https://docs.scala-lang.org) is +As [Heather Miller writes][why-contribute], contributing to [docs.scala-lang.org][home] is critical to making Scala accessible to newcomers, experience programmers, and anyone who is curious. It is also a fantastic way to contribute for anyone who is comfortable using Scala, but maybe does not want to get involved with complex tools like the compiler. @@ -45,7 +45,7 @@ For one to contribute a document, one must simply [repo](https://github.com/scala/docs.scala-lang), write their article in [Markdown](https://daringfireball.net/projects/markdown/syntax) (example below), and submit a pull request. That's it. Likely after some edits and discussion, your document will be made live -on [docs.scala-lang.org](https://docs.scala-lang.org). +on [docs.scala-lang.org][home]. --- layout: overview @@ -71,7 +71,7 @@ styling is already taken care of for you. ### Criteria for Docs to be Accepted The goal of this documentation repository is to be tighter and more organized than other community-driven documentation platforms, like wikis. As such, any document pulled in for inclusion on -[docs.scala-lang.org](https://docs.scala-lang.org) must: +[docs.scala-lang.org][home] must: - **"fit in"** to the repository ( _i.e.,_ it should not be a complete duplicate of another article), - **be polished** it must be thorough, complete, correct, organized, and "article-like" (personal programming notes @@ -129,7 +129,7 @@ documents in the large overview. Putting it on the last page in the overview is outof: 15 --- -Index pages, such as [docs.scala-lang.org/overviews/index.html](https://docs.scala-lang.org/overviews/index.html) are +Index pages, such as [docs.scala-lang.org/overviews/index.html][overviews-index] are generated, by reading data from a configuration file, such as `_data/overviews.yml`, so your overview should be placed into a category there. @@ -216,3 +216,6 @@ above. Here is an example using the various modifiers. [collections-overview]: {% link _overviews/collections-2.13/introduction.md %} [scala-with-maven]: {% link _overviews/tutorials/scala-with-maven.md %} +[why-contribute]: {% link contribute.md %} +[home]: {% link index.md %} +[overviews-index]: {% link _overviews/index.md %} diff --git a/_overviews/contribute/bug-reporting-guide.md b/_overviews/contribute/bug-reporting-guide.md index e2637ccd09..91858d589c 100644 --- a/_overviews/contribute/bug-reporting-guide.md +++ b/_overviews/contribute/bug-reporting-guide.md @@ -41,7 +41,7 @@ If you have a code snippet that is resulting in bytecode which you believe is be 5. If you want to file an improvement in the issue tracker please discuss it first on one of the mailing lists. They offer much bigger audience than issue tracker. The latter is not suitable for long discussions. -* Keep in mind that the behavior you are witnessing could be intended. Good formal resources for verifying whether or not the language behavior is intended is either in the [Scala Improvement Proposal Documents](https://docs.scala-lang.org/sips/) or in the [Scala Language Specification](https://www.scala-lang.org/files/archive/spec/2.13/). If in doubt, you may always ask on the [Community Category](https://contributors.scala-lang.org/c/community) or [Stack Overflow](https://stackoverflow.com/questions/tagged/scala). +* Keep in mind that the behavior you are witnessing could be intended. Good formal resources for verifying whether or not the language behavior is intended is either in the [Scala Improvement Proposal Documents][sips] or in the [Scala Language Specification](https://www.scala-lang.org/files/archive/spec/2.13/). If in doubt, you may always ask on the [Community Category](https://contributors.scala-lang.org/c/community) or [Stack Overflow](https://stackoverflow.com/questions/tagged/scala). In general, if you find yourself stuck on any of these steps, asking on [Scala Contributors](https://contributors.scala-lang.org/) can be helpful: @@ -85,3 +85,5 @@ List(1, 2, 3).map(x => x + 1) 3. The actual output, including the stacktrace. 4. Related discussion on the mailing lists, if applicable. 5. If you have already looked into the issue provide interesting insights or proposals for fixing the issue. + +[sips]: {% link _sips/index.md %} diff --git a/_overviews/contribute/codereviews.md b/_overviews/contribute/codereviews.md index 6325fcde6c..be8e66ba46 100644 --- a/_overviews/contribute/codereviews.md +++ b/_overviews/contribute/codereviews.md @@ -4,7 +4,7 @@ num: 3 --- ## Code Review Contributions -In addition to [bug fixing](/contribute/guide.html), you can help us review +In addition to [bug fixing][bug-fixing], you can help us review [waiting pull requests](#pull-requests-awaiting-comment). This is also a good (and recommended) way to get to know the feel of the bug-fixing and submissions process before jumping in with your @@ -54,4 +54,7 @@ own pull requests. -Also note that the [Tools contributions](/contribute/tools.html) page has more projects that will generate pull requests. +Also note that the [Tools contributions][tools] page has more projects that will generate pull requests. + +[bug-fixing]: {% link _overviews/contribute/guide.md %} +[tools]: {% link _overviews/contribute/tools.md %} diff --git a/_overviews/contribute/corelibs.md b/_overviews/contribute/corelibs.md index 3ee05e6c13..1eb2f840b0 100644 --- a/_overviews/contribute/corelibs.md +++ b/_overviews/contribute/corelibs.md @@ -6,12 +6,16 @@ num: 4 There are several options for contributing to Scala's core libraries. You can: -* Help with [Documentation](/contribute/documentation.html). -* [Report Bugs or Issues](/contribute/bug-reporting-guide.html) against the core libraries. -* [Fix Bugs or Issues](/contribute/guide.html) against the +* Help with [Documentation][documentation]. +* [Report Bugs or Issues][bug-reporting-guide] against the core libraries. +* [Fix Bugs or Issues][guide] against the [reported library bugs/issues](https://github.com/scala/bug). ### Significant changes For significant new functionality or a whole new API to be considered for inclusion in the core Scala distribution, please take into account [https://github.com/scala/scala-dev/issues/661] before doing so. + +[documentation]: {% link _overviews/contribute/documentation.md %} +[bug-reporting-guide]: {% link _overviews/contribute/bug-reporting-guide.md %} +[guide]: {% link _overviews/contribute/guide.md %} diff --git a/_overviews/contribute/documentation.md b/_overviews/contribute/documentation.md index 3d3311dbce..9bd4597b36 100644 --- a/_overviews/contribute/documentation.md +++ b/_overviews/contribute/documentation.md @@ -20,16 +20,16 @@ Thanks The Scala API documentation lives with the scala project source code. There are many ways you can help with improving Scaladoc, including: -* [Log issues for missing scaladoc documentation](/contribute/scala-standard-library-api-documentation.html#contribute-api-documentation-bug-reports) - +* [Log issues for missing scaladoc documentation][report-api-doc-bugs] - Please *follow the issue submission process closely* to help prevent duplicate issues being created. -* [Claim Scaladoc Issues and Provide Documentation](/contribute/scala-standard-library-api-documentation.html) - please claim issues prior to working on a specific scaladoc task to prevent duplication of effort. If you sit on an issue for too long without submitting a pull request, it will revert back to unassigned and you will need to re-claim it. +* [Claim Scaladoc Issues and Provide Documentation][scala-standard-library-api-documentation] - please claim issues prior to working on a specific scaladoc task to prevent duplication of effort. If you sit on an issue for too long without submitting a pull request, it will revert back to unassigned and you will need to re-claim it. * You can also just -[submit new Scaladoc](/contribute/scala-standard-library-api-documentation.html) +[submit new Scaladoc][scala-standard-library-api-documentation] without creating an issue, but please look to see if there is an issue already submitted for your task and claim it if there is. If not, please post your intention to work on a specific scaladoc task on [Scala Contributors](https://contributors.scala-lang.org/) so that people know what you are doing. ### The Main Scala Documentation Site -[docs.scala-lang.org](https://docs.scala-lang.org/) houses the primary source of written, non-API documentation for Scala. It's a GitHub project that you can fork and submit pull requests from. It includes: +[docs.scala-lang.org][home] houses the primary source of written, non-API documentation for Scala. It's a GitHub project that you can fork and submit pull requests from. It includes: * Overviews * Tutorials @@ -41,7 +41,7 @@ without creating an issue, but please look to see if there is an issue already s * SIP (Scala Improvement Process) Proposals and more -Please read [Add New Guides/Tutorials](/contribute/add-guides.html) through before embarking on changes. The site uses +Please read [Add New Guides/Tutorials][add-guides] through before embarking on changes. The site uses the [Jekyll](https://jekyllrb.com/) markdown engine so you will need to follow the instructions to get that running as well. ### Updating scala-lang.org @@ -52,4 +52,9 @@ to Scala and related projects) is provided on the main [scala-lang GitHub project](https://github.com/scala/scala-lang) which may be forked to create pull requests. Please read both the -[Add New Guides/Tutorials](/contribute/add-guides.html) document and the [scala-lang.org GitHub README](https://github.com/scala/scala-lang#scala-langorg) before embarking on any changes to the Scala language site, as it uses the same Jekyll markdown tool and many of the same conventions as the Scala documentation site. +[Add New Guides/Tutorials][add-guides] document and the [scala-lang.org GitHub README](https://github.com/scala/scala-lang#scala-langorg) before embarking on any changes to the Scala language site, as it uses the same Jekyll markdown tool and many of the same conventions as the Scala documentation site. + +[report-api-doc-bugs]: {% link _overviews/contribute/scala-standard-library-api-documentation.md %}#contribute-api-documentation-bug-reports +[scala-standard-library-api-documentation]: {% link _overviews/contribute/scala-standard-library-api-documentation.md %} +[home]: {% link index.md %} +[add-guides]: {% link _overviews/contribute/add-guides.md %} diff --git a/_overviews/contribute/guide.md b/_overviews/contribute/guide.md index 70d470d454..472d2d41ab 100644 --- a/_overviews/contribute/guide.md +++ b/_overviews/contribute/guide.md @@ -38,19 +38,19 @@ unencumbered by copyrights or patents. This is the impatient developer's checklist for the steps to submit a bug-fix pull request to the Scala project. For more information, description and justification for the steps, follow the links in that step. Further specific instructions for the release of Scala you are targeting can be found in the `CONTRIBUTING.md` file for that [GitHub branch](https://github.com/scala/scala) -1. [Select a bug to fix from GitHub](/contribute/index.html#community-tickets), or if you found the bug yourself and want to fix it, [create a GitHub issue](/contribute/bug-reporting-guide.html) (but please -[make sure it's not a duplicate](/contribute/bug-reporting-guide.html#please-check-before-reporting-a-bug)). -2. Optional ([but recommended](/contribute/scala-internals.html/#why-its-a-good-idea)), announce your intention to work on the bug on [Scala Contributors](https://contributors.scala-lang.org/). After all, don't you want to work on a team with -[these friendly people](/contribute/hacker-guide.html#1-connect) - it's one of the perks of contributing. -3. [Fork the Scala repository](/contribute/hacker-guide.html#fork) and clone your fork (if you haven't already). -4. [Create a feature branch](/contribute/hacker-guide.html#branch) to work on: use the branch name `issue/NNNN` where NNNN is the GitHub issue number. -5. [Fix the bug, or implement the new small feature](/contribute/hacker-guide.html#implement), include new tests (yes, for bug fixes too). -6. [Test, rinse](/contribute/hacker-guide.html#test) and [test some more](/contribute/partest-guide.html) until [all the tests pass](/contribute/hacker-guide.html#verify). -7. [Commit your changes](/contribute/hacker-guide.html#commit) to your feature branch in your fork. Please choose your commit message based on the [Git Hygiene](https://github.com/scala/scala#user-content-git-hygiene) section of the Scala project README. +1. [Select a bug to fix from GitHub][community-tickets], or if you found the bug yourself and want to fix it, [create a GitHub issue][bug-reporting-guide] (but please +[make sure it's not a duplicate][bug-report-check-dupes]). +2. Optional ([but recommended][why-its-a-good-idea]), announce your intention to work on the bug on [Scala Contributors](https://contributors.scala-lang.org/). After all, don't you want to work on a team with +[these friendly people][hackers-connect] - it's one of the perks of contributing. +3. [Fork the Scala repository][hackers-fork] and clone your fork (if you haven't already). +4. [Create a feature branch][hackers-branch] to work on: use the branch name `issue/NNNN` where NNNN is the GitHub issue number. +5. [Fix the bug, or implement the new small feature][hackers-implement], include new tests (yes, for bug fixes too). +6. [Test, rinse][hackers-test] and [test some more][partest-guide] until [all the tests pass][hackers-verify]. +7. [Commit your changes][hackers-commit] to your feature branch in your fork. Please choose your commit message based on the [Git Hygiene](https://github.com/scala/scala#user-content-git-hygiene) section of the Scala project README. 8. If necessary [re-write git history](https://git-scm.com/book/en/Git-Branching-Rebasing) so that [commits are organized by major steps to the fix/feature]( https://github.com/scala/scala#git-hygiene). For bug fixes, a single commit is requested, for features several commits may be desirable (but each separate commit must compile and pass all tests) -9. [Submit a pull request](/contribute/hacker-guide.html#submit). -10. [Work with a reviewer](https://github.com/scala/scala#reviewing) to [get your pull request merged in](/contribute/hacker-guide.html#review). +9. [Submit a pull request][hackers-submit]. +10. [Work with a reviewer](https://github.com/scala/scala#reviewing) to [get your pull request merged in][hackers-review]. 11. Celebrate! Need more information or a little more hand-holding for the first one? We got you covered: take a read through the entire [Hacker Guide][hackers] (or the [equivalent Scala 3 Contributing Guide][scala3-hackers]) for an example of implementing a new feature (some of the steps can be skipped for bug fixes, this will be obvious from reading it, but many of the steps here will help with bug fixes too). @@ -59,13 +59,26 @@ Need more information or a little more hand-holding for the first one? We got yo For larger, more ambitious changes (e.g. new language features), the first step to making a change is to discuss it with the community at large, to make sure everyone agrees on the idea and on the implementation plan. Announce the change -on the [Scala Contributors](https://contributors.scala-lang.org/) mailing list and get developer feedback. For really complex changes, a [Scala Improvement Process (SIP)](https://docs.scala-lang.org/sips/) document might be required, but the first step is always to discuss it on the mailing list and if a SIP is required, that will be discussed on the mailing list. +on the [Scala Contributors](https://contributors.scala-lang.org/) mailing list and get developer feedback. For really complex changes, a [Scala Improvement Process (SIP)][sips] document might be required, but the first step is always to discuss it on the mailing list and if a SIP is required, that will be discussed on the mailing list. Contributions, big or small, simple or complex, controversial or undisputed, need to materialize as patches against the Scala project source tree. The hacker's guides ([Scala 2][hackers], or [Scala 3][scala3-hackers]) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. -[hackers]: /contribute/hacker-guide.html -[community-tickets]: /contribute/index.html#community-tickets -[bug-reporting-guide]: /contribute/bug-reporting-guide.html +[hackers]: {% link _overviews/contribute/hacker-guide.md %} +[community-tickets]: {% link _overviews/contribute/index.md %}#community-tickets +[bug-reporting-guide]: {% link _overviews/contribute/bug-reporting-guide.md %} +[bug-report-check-dupes]: {% link _overviews/contribute/bug-reporting-guide.md %}#please-check-before-reporting-a-bug [scala3-hackers]: {% link _overviews/scala3-contribution/procedures-intro.md %} [contrib-forum]: https://contributors.scala-lang.org/ +[why-its-a-good-idea]: {% link _overviews/contribute/scala-internals.md %}#why-its-a-good-idea +[hackers-connect]: {% link _overviews/contribute/hacker-guide.md %}#1-connect +[hackers-fork]: {% link _overviews/contribute/hacker-guide.md %}#fork +[hackers-branch]: {% link _overviews/contribute/hacker-guide.md %}#branch +[hackers-implement]: {% link _overviews/contribute/hacker-guide.md %}#implement +[hackers-test]: {% link _overviews/contribute/hacker-guide.md %}#test +[hackers-verify]: {% link _overviews/contribute/hacker-guide.md %}#verify +[hackers-commit]: {% link _overviews/contribute/hacker-guide.md %}#commit +[hackers-submit]: {% link _overviews/contribute/hacker-guide.md %}#submit +[hackers-review]: {% link _overviews/contribute/hacker-guide.md %}#review +[partest-guide]: {% link _overviews/contribute/partest-guide.md %} +[sips]: {% link _sips/index.md %} diff --git a/_overviews/contribute/hacker-guide.md b/_overviews/contribute/hacker-guide.md index f9db614056..92181003fa 100644 --- a/_overviews/contribute/hacker-guide.md +++ b/_overviews/contribute/hacker-guide.md @@ -196,7 +196,7 @@ Contributing to the Scala standard library is about the same as working on one o If documentation is necessary for some trait/class/object/method/etc in the Scala standard library, typically maintainers will include inline comments describing their design decisions or rationale for implementing things the way they have, if it is not straightforward. -If you intend on contributing to Scala collections, please make sure you're familiar with the design of the Scala collections library. It can be easy to put an implementation in the wrong location if you are unfamiliar with the collections architecture. There is an excellent and very detailed guide covering [the Architecture of Scala Collections](/overviews/core/architecture-of-scala-collections.html), as well as a larger more general [Scala collections Guide](/overviews/collections/introduction.html) covering the sequential portion of collections. For parallel collections, there also exists a detailed [Scala Parallel Collections Guide](/overviews/parallel-collections/overview.html). +If you intend on contributing to Scala collections, please make sure you're familiar with the design of the Scala collections library. It can be easy to put an implementation in the wrong location if you are unfamiliar with the collections architecture. There is an excellent and very detailed guide covering [the Architecture of Scala Collections][collections-arch], as well as a larger more general [Scala collections Guide][collections-intro] covering the sequential portion of collections. For parallel collections, there also exists a detailed [Scala Parallel Collections Guide][collections-par]. ##### The Scala Compiler @@ -204,7 +204,7 @@ Documentation about the internal workings of the Scala compiler is scarce, and m * [Compiler internals videos by Martin Odersky](https://www.scala-lang.org/old/node/598.html) are quite dated, but still very useful. In this three-video series Martin explains the general architecture of the compiler, and the basics of the front-end, which has recently become Scala reflection API. -* [Reflection documentation](/overviews/reflection/overview.html) describes fundamental data structures (like `Tree`s, `Symbol`s, and `Types`) that +* [Reflection documentation][reflect-overview] describes fundamental data structures (like `Tree`s, `Symbol`s, and `Types`) that are used to represent Scala programs and operations defined on then. Since much of the compiler has been factored out and made accessible via the Reflection API, all of the fundamentals needed for reflection are the same for the compiler. * [Reflection and Compilers by Martin Odersky](https://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Reflection-and-Compilers), a talk at Lang.NEXT 2012 in which Martin elaborates on the design of scalac and the architecture of the reflection API. @@ -307,7 +307,7 @@ This means your change is backward or forward binary incompatible with the speci ### Verify -Now to make sure that my fix doesn't break anything I need to run the test suite. The Scala test suite uses [JUnit](https://junit.org/junit4/) and [partest](/contribute/partest-guide.html), a tool we wrote for testing Scala. +Now to make sure that my fix doesn't break anything I need to run the test suite. The Scala test suite uses [JUnit](https://junit.org/junit4/) and [partest][partest-guide], a tool we wrote for testing Scala. Run `sbt test` and `sbt partest` to run all of the JUnit and partest tests, respectively. `partest` (not `sbt partest`) also allows you to run a subset of the tests using wildcards: @@ -378,3 +378,9 @@ workflow) and be ready to elaborate and adjust your patch if necessary. In this After your reviewer is happy with your code (usually signaled by a LGTM — “Looks good to me”), your job is done. Note that there can be a gap between a successful review and the merge, because not every reviewer has merge rights. In that case, someone else from the team will pick up your pull request and merge it. So don't be confused if your reviewer says “LGTM”, but your code doesn't get merged immediately. + +[collections-arch]: {% link _overviews/core/architecture-of-scala-collections.md %} +[collections-intro]: {% link _overviews/collections/introduction.md %} +[collections-par]: {% link _overviews/parallel-collections/overview.md %} +[reflect-overview]: {% link _overviews/reflection/overview.md %} +[partest-guide]: {% link _overviews/contribute/partest-guide.md %} diff --git a/_overviews/contribute/index.md b/_overviews/contribute/index.md index eb0596d802..4e94334061 100644 --- a/_overviews/contribute/index.md +++ b/_overviews/contribute/index.md @@ -15,7 +15,7 @@ That depends on what you want to contribute. Below are some getting started reso ### Reporting bugs -See our [bug reporting guide](/contribute/bug-reporting-guide.html) to learn +See our [bug reporting guide][bug-reporting-guide] to learn how to efficiently report a bug. ### Contribute @@ -30,7 +30,7 @@ Coordination of contribution efforts takes place on When contributing, please follow: * The [Scala Code of Conduct](https://scala-lang.org/conduct/) -* The [Inclusive Language Guide](/contribute/inclusive-language-guide.html) +* The [Inclusive Language Guide][inclusive-language-guide] ### Community Tickets @@ -63,3 +63,6 @@ open-source Scala library or tool, please visit the [community build documentation](https://github.com/scala/community-build/wiki) for guidelines on what projects are suitable for the community build and how projects can be added. + +[bug-reporting-guide]: {% link _overviews/contribute/bug-reporting-guide.md %} +[inclusive-language-guide]: {% link _overviews/contribute/inclusive-language-guide.md %} diff --git a/_overviews/contribute/scala-standard-library-api-documentation.md b/_overviews/contribute/scala-standard-library-api-documentation.md index 606407f886..c1303e8b18 100644 --- a/_overviews/contribute/scala-standard-library-api-documentation.md +++ b/_overviews/contribute/scala-standard-library-api-documentation.md @@ -9,8 +9,8 @@ documentation for sometimes referred to as Scaladoc contributions. For contributions to tutorial and guide-style documentation on -[docs.scala-lang.org](/), -see [Add New Guides/Tutorials](/contribute/add-guides.html). +[docs.scala-lang.org][home], +see [Add New Guides/Tutorials][add-guides]. *Please note, these instructions cover documentation contributions Scala core libraries only. For other Scala projects please check those projects for the @@ -76,13 +76,13 @@ component so that they show up in the correct issue filters. Please familiarize yourself with the following before contributing new API documentation to save time, effort, mistakes and repetition. -* [Forking the Repo](/contribute/hacker-guide.html#2-set-up) - follow the setup steps through +* [Forking the Repo][hackers-setup] - follow the setup steps through the Branch section. If providing new documentation related to an existing GitHub issue, use `issue/NNNN` or `ticket/NNNN` as the guide states. If providing API documentation with no associated GitHub issue, use `scaladoc/xxxx` instead. -* [Scaladoc for library authors](https://docs.scala-lang.org/overviews/scaladoc/for-library-authors.html) +* [Scaladoc for library authors][scaladoc-lib-authors] covers the use of scaladoc tags, markdown and other features. -* [Scaladoc's interface](https://docs.scala-lang.org/overviews/scaladoc/interface.html) +* [Scaladoc's interface][scaladoc-interface] covers all of the features of Scaladoc's interface, e.g. switching between companions, browsing package object documentation, searching, token searches and so on. @@ -121,3 +121,9 @@ PR is merged in smoothly: as smooth and streamlined as possible. Thanks for helping us improve the Scaladoc API documentation! + +[home]: {% link index.md %} +[add-guides]: {% link _overviews/contribute/add-guides.md %} +[hackers-setup]: {% link _overviews/contribute/hacker-guide.md %}#2-set-up +[scaladoc-lib-authors]: {% link _overviews/scaladoc/for-library-authors.md %} +[scaladoc-interface]: {% link _overviews/scaladoc/interface.md %} From 7de6290af5657b4a02373222452f25daca0fe0c8 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Wed, 23 Mar 2022 18:01:50 +0100 Subject: [PATCH 1809/3075] add back Scoverage as a project in need --- _overviews/contribute/tools.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/_overviews/contribute/tools.md b/_overviews/contribute/tools.md index 68cee7796f..77115d03ab 100644 --- a/_overviews/contribute/tools.md +++ b/_overviews/contribute/tools.md @@ -30,6 +30,14 @@ projects: contributingLink: projectsInNeed: + - title: Scoverage + description: Scala code coverage tool + icon: https://avatars1.githubusercontent.com/u/5998302?v=3&s=200 + link: https://github.com/scoverage/scalac-scoverage-plugin + homeLink: http://scoverage.org/ + issuesLink: https://github.com/scoverage/scalac-scoverage-plugin/issues + readmeLink: https://github.com/scoverage/scalac-scoverage-plugin/blob/master/README.md + contributingLink: https://groups.google.com/forum/#!forum/scala-code-coverage-tool --- ## Contributing to IDE and Build Tools From e2a41dc6ad52aad13d3e07acc1971c3cbc859344 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Wed, 23 Mar 2022 19:41:21 +0100 Subject: [PATCH 1810/3075] use more accessible language in Add New Guides/Tutorials - also switch some code blocks to explicit html so that mdoc code blocks are not escaped. --- _overviews/contribute/add-guides.md | 204 +++++++++++++++++----------- 1 file changed, 126 insertions(+), 78 deletions(-) diff --git a/_overviews/contribute/add-guides.md b/_overviews/contribute/add-guides.md index 96091fb311..ed8b0d36c7 100644 --- a/_overviews/contribute/add-guides.md +++ b/_overviews/contribute/add-guides.md @@ -19,8 +19,11 @@ and is always contribution-ready. Currently, the _types_ of documentation supported in this repository are: -- **Guides/Overviews**: Definitive guides/overviews of specific language features. Often long, detailed documents, - often produced by members of the Scala team. An example is the excellent [Collections][collections-overview] overview. +- **Guides/Overviews/Books**: Definitive guides/overviews of specific language features. Often long, detailed documents, + often produced by members of the Scala team. An example is the [Collections][collections-overview] overview. +- **References**: The canonical reference for language features, written by members of the Scala team. + These provide the exact specification to understand more subtle aspects of the language. An example is the + [Scala 3 reference][scala-3-reference]. - **Tutorials**: Bite-size, example-rich, and concise articles meant to get a developer up to speed quickly. - **Cheatsheets**: Quick reference of Scala syntax and behaviors. @@ -28,27 +31,29 @@ Currently, the _types_ of documentation supported in this repository are: The website is statically generated from [Markdown](https://en.wikipedia.org/wiki/Markdown) source using [Jekyll](https://github.com/mojombo/jekyll), and hosted on [GitHub Pages](https://pages.github.com/). -This workflow was chosen so as to make it as easy as possible for core committers and the community alike -to produce HTML documentation, and as easy as possible to publish it in a central location. +This workflow was chosen to help contributors to focus on writing helpful content, rather than on configuration and +boilerplate. It also aids publishing a static site in a central location. The markdown syntax being used supports [Maruku](https://github.com/bhollis/maruku) extensions, and has automatic syntax highlighting, without the need for any tags. Additionally [mdoc](https://github.com/scalameta/mdoc) is used during pull requests to validate Scala code blocks. -To use this feature you must use the backtick notation as documented by mdoc. Note that only validation is done. -The output files from mdoc are not used in the building of the tutorial. Use `mdoc` or `mdoc:fail` for your code blocks. +To use this feature you must use the backtick notation as documented by mdoc, +[see here](#code-blocks) for an example. + +**Note:** only validation of code is done by mdoc, and no extra output is generated. ## Submitting Docs -For one to contribute a document, one must simply +For you to contribute a document, first [fork](https://help.github.com/articles/fork-a-repo/) the -[repo](https://github.com/scala/docs.scala-lang), write their article in -[Markdown](https://daringfireball.net/projects/markdown/syntax) (example below), and submit a pull request. That's it. +[repo](https://github.com/scala/docs.scala-lang), then write your article in +[Markdown](https://daringfireball.net/projects/markdown/syntax) (example below), and finally submit a pull request. Likely after some edits and discussion, your document will be made live on [docs.scala-lang.org][home]. --- - layout: overview + layout: singlepage-overview title: My Awesome Title --- @@ -56,32 +61,41 @@ on [docs.scala-lang.org][home]. And a paragraph, with a [link](https://www.scala-lang.org). -One can contribute code in a markdown document by either - - indenting it by 4 spaces - - surrounding by triple backticks, as shown below - - in-line by putting backticks around it, e.g. `def foo`. +You can contribute code in a markdown document by either +- in-line by putting backticks around it, +- surrounding by triple backticks, +- or indenting it by 4 spaces, e.g.: + +~~~ +inline example: `val x = 23` + +block example: +```scala +println("hello") +``` + +indented example: - ```scala - println("hello") - ``` + case class Foo(x: Int) +~~~ -Everything else is automatically generated for you; tables of contents, and most index pages. And of course, the -styling is already taken care of for you. +Tables of contents will be automatically generated in a sidebar for your document, and syntax highlighting +is provided. ### Criteria for Docs to be Accepted -The goal of this documentation repository is to be tighter and more organized than other community-driven documentation platforms, like wikis. As such, any document pulled in for inclusion on -[docs.scala-lang.org][home] must: +The goal of this documentation repository is to be highly curated, rather than the approach by other community-driven +documentation platforms, like wikis. Therefore, to be included on [docs.scala-lang.org][home], a document must: - **"fit in"** to the repository ( _i.e.,_ it should not be a complete duplicate of another article), -- **be polished** it must be thorough, complete, correct, organized, and "article-like" (personal programming notes -don't quite fit.) -- **be maintained** if the document might require revisions from time to time, be prepared to keep it up to date, or +- **be polished**, i.e. it must be thorough, complete, correct, and organized; written as an article to be understood + by many users. +- **be maintained**, if the document might require revisions from time to time, be prepared to keep it up to date, or nominate someone to take ownership. If you have something you're thinking about contributing, or that you're thinking about writing in order to contribute -- we'd love to consider it! Please don't hesitate to use GitHub issues and pull requests and the -\#scala-contributors room [on Discord](https://discord.com/invite/scala) for any questions, concerns, +`#scala-contributors` room [on Discord](https://discord.com/invite/scala) for any questions, concerns, clarifications, etc. ## Document Templates @@ -90,38 +104,36 @@ clarifications, etc. ### Guides/Overviews -A guide or an overview that can be logically placed on **one** page must be placed in the directory -`_overviews/RELEVANT-CATEGORY/_posts` with the file name in the format `YYYY-MM-dd-title-separated-by-dashes.md`, -and header: +A guide or an overview that can be logically placed on **one** markdown page should be placed in the directory +`_overviews/RELEVANT-CATEGORY/`. It should have the header: --- - layout: overview + layout: singlepage-overview title: YOUR TITLE --- -The rest of the document should, of course, be written in [Markdown](https://en.wikipedia.org/wiki/Markdown). +The rest of the document will be written in [Markdown](https://en.wikipedia.org/wiki/Markdown) syntax. -At the moment, `RELEVANT-CATEGORY` corresponds to only a single category, "core," because we are currently focusing on -building up documentation of core libraries. However, expect more categories here in the future. +You may substitute `RELEVANT-CATEGORY` for any directory that is related, or create a new one if one is not suitable. -If your document consists of **multiple** pages, like the [Collections][collections-overview] overview, an ordering -must be specified, by numbering documents in their logical order with `num`, and a name must be assigned to the -collection of pages using `partof`. For example, the following header might be used for a document in the collections -overview: +If your guide/overview consists of **multiple** pages, like the [Collections][collections-overview] overview, +an ordering must be specified, by numbering documents in their logical order with the `num` tag in the header, +and a name must be assigned to the collection of pages using the `partof` tag. +For example, the following header might be used for a document in the collections overview: --- - layout: overview + layout: multipage-overview title: YOUR TITLE partof: collections num: 10 --- -A **single** document in the collection must contain a tag in the header, `outof`, that indicates the total number of -documents in the large overview. Putting it on the last page in the overview is often best: +**At least one** document in the collection must contain a tag in the header, `outof`, that indicates the total number +of documents in the large overview. Putting it on the last page in the overview is often best: --- - layout: overview + layout: multipage-overview title: YOUR TITLE partof: collections @@ -130,14 +142,18 @@ documents in the large overview. Putting it on the last page in the overview is --- Index pages, such as [docs.scala-lang.org/overviews/index.html][overviews-index] are -generated, by reading data from a configuration file, such as `_data/overviews.yml`, so your overview should be +generated by reading data from a configuration file, such as `_data/overviews.yml`, so your overview should be placed into a category there. ### Tutorials -At the moment, tutorials are written the same as Guides/Overviews, except that their link must be added to -the metadata of `/tutorials.md`. e.g. for the [Scala With Maven][scala-with-maven] tutorial, the -metadata of `/tutorials.md` looks like +Tutorials are different to guides, they should be written in a much more concise, task-oriented style, +usually on a single page. + +Similar to guides, tutorials also use the same markdown header. + +Once the tutorial is written, to aid user navigation their link must be added to +the metadata of `/tutorials.md`. e.g. it could look like --- layout: inner-page-parent @@ -145,18 +161,33 @@ metadata of `/tutorials.md` looks like tutorials: ... - - title: "Scala with Maven" - url: "/tutorials/scala-with-maven.html" - description: "Create a Scala project with Maven." - icon: code + - title: My New Tutorial + url: "/tutorials/my-new-tutorial.html" + description: "Learn How To Do This Specific Task" + icon: code --- -For a single-page tutorial, the typical directory to place them in is `_overviews/tutorials`. +You must also add the tutorial to the drop down list in the navigation bar. To do this, add an extra entry to +`_data/doc-nav-header.yml`. i.e. + + --- + - title: Getting Started + url: "/getting-started/index.html" + - title: Learn + ... + - title: Tutorials + url: "#" + submenu: + ... + - title: My New Tutorial + url: "/tutorials/my-new-tutorial.html" + ... + --- ### Cheatsheets -For now, cheatsheets are assumed to be in the form of tables. To contribute a cheatsheet, one must simply produce their -cheatsheet as a Markdown table, with the following header: +Cheatsheets have a special layout, and the content is expected to be a markdown table. To contribute a cheatsheet, +you should use the following format: --- layout: cheatsheet @@ -164,27 +195,37 @@ cheatsheet as a Markdown table, with the following header: by: YOUR NAME about: SOME TEXT ABOUT THE CHEAT SHEET. --- + | Title A | Title B | + |---------|---------| + | content | more | ### Code blocks The site build process uses [mdoc](https://scalameta.org/mdoc/) to typecheck code snippets in markdown. This is a great way to ensure the code snippets that -you're including typecheck and are valid. Here are a few quick types to get -started. +you're including typecheck and are valid. Here are a few quick tips to get +started: -To get started, add `mdoc` after `scala` when you are creating a +First, add `mdoc` after `scala` when you are creating a code block. The `mdoc` modifier here will make sure that `mdoc` runs the code snippet and ensures that it's valid. - ```scala mdoc - val a = 1 - ``` +
+
+
+            ```scala mdoc
+val a = 1
+```
+
+ If you have a snippet that you expect to fail, you can also account for this by using `mdoc:fail` for a compile error `mdoc:crash` for a runtime-error. - ```scala mdoc:fail - val b: String = 3 // won't compile - ``` +
```scala mdoc:fail
+val b: String = 3 // won't compile
+```
+
+ Keep in mind that a single file is all compiled as a single unit, so you can't redefine a variable that was defined above in another code snippet. _However_ there are a couple ways to get around this. Firstly, you can use the `mdoc:nest` @@ -193,29 +234,36 @@ essentially "hide" the snippet from the others. Another way around this is to use the `mdoc:reset` modifier, which _resets_ and forgets about everything up above. Here is an example using the various modifiers. - ```scala mdoc - import java.time.Instant +
```scala mdoc
+import java.time.Instant
+
+def now() = Instant.now()
+object Foo {}
+```
+
+ +
```scala mdoc:nest
+case class Foo(a: Int) // conflicts with Foo above, but it's nested so it's fine
+```
+
- def now() = Instant.now() - object Foo {} - ``` +
```scala mdoc
+val a = s"The time is ${now()}" // still have access to the now method from above
+```
+
- ```scala mdoc:nest - case class Foo(a: Int) // conflicts with Foo above, but it's nested so it's fine - ``` +
```scala mdoc:reset
+case class Foo(a: String) // forget the previous Foo's and start fresh
+```
+
- ```scala mdoc - val a = s"The time is ${now()}" // still have access to the now method from above - ``` - ```scala mdoc:reset - case class Foo(a: String) // forget the previous Foo's and start fresh - ``` - ```scala mdoc - val myFoo = Foo("hi") // now we only have access to the last Foo - ``` +
```scala mdoc
+val myFoo = Foo("hi") // now we only have access to the last Foo
+```
+
[collections-overview]: {% link _overviews/collections-2.13/introduction.md %} -[scala-with-maven]: {% link _overviews/tutorials/scala-with-maven.md %} [why-contribute]: {% link contribute.md %} [home]: {% link index.md %} [overviews-index]: {% link _overviews/index.md %} +[scala-3-reference]: https://docs.scala-lang.org/scala3/reference/overview.html From d8e9d2ebc889dc4b7e5a22530596bc9b6d7f24aa Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Wed, 23 Mar 2022 19:58:56 +0100 Subject: [PATCH 1811/3075] enhance contribute intro --- _contribute_resources/1-documentation.md | 4 +++- _overviews/contribute/index.md | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/_contribute_resources/1-documentation.md b/_contribute_resources/1-documentation.md index 1f42a6e20b..e11b539e16 100644 --- a/_contribute_resources/1-documentation.md +++ b/_contribute_resources/1-documentation.md @@ -3,7 +3,9 @@ title: Documentation link: /contribute/documentation.html icon: fa fa-book --- -[Scaladoc (API)][scala-standard-library-api-documentation], [docs.scala-lang.org][add-guides] and [scala-lang.org](https://github.com/scala/scala-lang). +[Library API docs][scala-standard-library-api-documentation], [new guides][add-guides] on [docs.scala-lang.org][home], and help +with [scala-lang.org](https://github.com/scala/scala-lang). [add-guides]: {% link _overviews/contribute/add-guides.md %} [scala-standard-library-api-documentation]: {% link _overviews/contribute/scala-standard-library-api-documentation.md %} +[home]: {% link index.md %} diff --git a/_overviews/contribute/index.md b/_overviews/contribute/index.md index 4e94334061..da197e233e 100644 --- a/_overviews/contribute/index.md +++ b/_overviews/contribute/index.md @@ -1,16 +1,16 @@ --- -title: Contribute +title: Introduction num: 1 --- +### Why You Should Contribute To Scala The Scala programming language is an open source project with a very diverse community, where people from all over the world contribute their work, with everyone benefiting from friendly help and advice, and kindly helping others in return. So why not join the Scala community and help everyone make things better? -## How to help? - +**What Can I Do?** That depends on what you want to contribute. Below are some getting started resources for different contribution domains. Please read all of the documentation and follow all the links from the topic pages below before attempting to contribute, as many of the questions you have will already be answered. ### Reporting bugs From 7282312e59bc4a38a1bf508e01ad7342cea386c9 Mon Sep 17 00:00:00 2001 From: Florian3k <24961583+Florian3k@users.noreply.github.com> Date: Sat, 26 Mar 2022 13:07:21 +0100 Subject: [PATCH 1812/3075] Remove dangling opening brace --- _overviews/scala3-book/fp-functional-error-handling.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-book/fp-functional-error-handling.md b/_overviews/scala3-book/fp-functional-error-handling.md index d56dfff3a6..41410e5cf1 100644 --- a/_overviews/scala3-book/fp-functional-error-handling.md +++ b/_overviews/scala3-book/fp-functional-error-handling.md @@ -137,7 +137,7 @@ val stringA = "1" val stringB = "2" val stringC = "3" -val y = for { +val y = for a <- makeInt(stringA) b <- makeInt(stringB) c <- makeInt(stringC) From 7a3468bec81c9382d37a10e6d2be5c928d4000db Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Sat, 26 Mar 2022 16:56:46 -0700 Subject: [PATCH 1813/3075] Give Nth advice --- _overviews/core/collections-migration-213.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/_overviews/core/collections-migration-213.md b/_overviews/core/collections-migration-213.md index 68c5247774..114da1f632 100644 --- a/_overviews/core/collections-migration-213.md +++ b/_overviews/core/collections-migration-213.md @@ -15,6 +15,8 @@ The most important changes in the Scala 2.13 collections library are: - Transformation methods no longer have an implicit `CanBuildFrom` parameter. This makes the library easier to understand (in source code, Scaladoc, and IDE code completion). It also makes compiling user code more efficient. - The type hierarchy is simplified. `Traversable` no longer exists, only `Iterable`. - The `to[Collection]` method was replaced by the `to(Collection)` method. + - The `toC` methods are strict by convention and yield the default collection type where applicable. For example, `Iterator.continually(42).take(10).toSeq` produces a `List[Int]` and without the limit would not. + - `toIterable` is deprecated wherever defined. For `Iterator`, in particular, prefer `to[LazyList]`. - Views have been vastly simplified and work reliably now. They no longer extend their corresponding collection type, for example, an `IndexedSeqView` no longer extends `IndexedSeq`. - `collection.breakOut` no longer exists, use `.view` and `.to(Collection)` instead. - Immutable hash sets and hash maps have a new implementation (`ChampHashSet` and `ChampHashMap`, based on the ["CHAMP" encoding](https://michael.steindorfer.name/publications/oopsla15.pdf)). From f874fe30c3d6c2b68483281ceadcc51b5620f301 Mon Sep 17 00:00:00 2001 From: som-snytt Date: Sat, 26 Mar 2022 18:35:24 -0700 Subject: [PATCH 1814/3075] Relax it's private --- _tour/classes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_tour/classes.md b/_tour/classes.md index ee3dc33703..0bda77c78e 100644 --- a/_tour/classes.md +++ b/_tour/classes.md @@ -86,7 +86,7 @@ class Point { if (newValue < bound) _y = newValue else printWarning() } - private def printWarning(): Unit = println("WARNING: Out of bounds") + private def printWarning() = println("WARNING: Out of bounds") } val point1 = new Point From e6f52d94d532d7f6d8a07d8e5bac6a46ef11cf30 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Sat, 26 Mar 2022 22:14:41 -0700 Subject: [PATCH 1815/3075] Lower bound in tour includes dangers --- _tour/lower-type-bounds.md | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/_tour/lower-type-bounds.md b/_tour/lower-type-bounds.md index a1cdb9648f..548ffb733b 100644 --- a/_tour/lower-type-bounds.md +++ b/_tour/lower-type-bounds.md @@ -42,26 +42,40 @@ trait Node[+B] { def prepend[U >: B](elem: U): Node[U] } -case class ListNode[+B](h: B, t: Node[B]) extends Node[B] { +case class ListNode[+B](head: B, tail: Node[B]) extends Node[B] { def prepend[U >: B](elem: U): ListNode[U] = ListNode(elem, this) - def head: B = h - def tail: Node[B] = t } -case class Nil[+B]() extends Node[B] { - def prepend[U >: B](elem: U): ListNode[U] = ListNode(elem, this) +object Nil extends Node[Nothing] { + def prepend[U >: Nothing](elem: U): ListNode[U] = ListNode(elem, this) } ``` +We have also simplified `ListNode` to leverage its `case class` fields, and `Nil` to be a singleton object; it is a "node of nothing" because it does not hold an element. The type parameter for `Node` is `B` to suggest we want to store birds at each node. + Now we can do the following: ```scala mdoc trait Bird case class AfricanSwallow() extends Bird case class EuropeanSwallow() extends Bird +val africanSwallows: Node[AfricanSwallow] = ListNode[AfricanSwallow](AfricanSwallow(), Nil) +val swallowsFromAntarctica: Node[Bird] = Nil -val africanSwallowList = ListNode[AfricanSwallow](AfricanSwallow(), Nil()) -val birdList: Node[Bird] = africanSwallowList -birdList.prepend(EuropeanSwallow()) +// assign swallows to birds +val birds: Node[Bird] = africanSwallows + +// add a swallow to birds +val moreBirds = birds.prepend(EuropeanSwallow()) + +// add disparate swallows together to get birds +val allBirds = africanSwallows.prepend(EuropeanSwallow()) + +// but this is a mistake! adding a Node to birds widens the type arg too much. -Xlint will warn! +val error = moreBirds.prepend(swallowsFromAntarctica) ``` -The `Node[Bird]` can be assigned the `africanSwallowList` but then accept `EuropeanSwallow`s. +The covariant type parameter allows `birds` to get the value of `africanSwallows`. + +The type bound on the type parameter for `prepend` allows adding different varieties of swallows and getting a wider type: instead of `Node[AfricanSwallow]`, we get a `Node[Bird]`. + +The canary in the coal mine is `-Xlint`, which will warn if the type arg is widened too much. From e2f00f6c39981cdbeeaf5688b9f374904e403574 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Tue, 29 Mar 2022 18:10:06 +0200 Subject: [PATCH 1816/3075] Add parentheses to hello method definition Fixes #2357 --- _overviews/scala3-book/taste-hello-world.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-book/taste-hello-world.md b/_overviews/scala3-book/taste-hello-world.md index 7acf47e20e..110d55ba91 100644 --- a/_overviews/scala3-book/taste-hello-world.md +++ b/_overviews/scala3-book/taste-hello-world.md @@ -12,7 +12,7 @@ A Scala 3 “Hello, world!” example goes as follows. First, put this code in a file named _Hello.scala_: ```scala -@main def hello = println("Hello, world!") +@main def hello() = println("Hello, world!") ``` In this code, `hello` is a method. From 4895a4b7cc34c786937d1ef5c198bce66ab8777c Mon Sep 17 00:00:00 2001 From: som-snytt Date: Tue, 29 Mar 2022 09:49:23 -0700 Subject: [PATCH 1817/3075] Fix brackets Co-authored-by: Julien Richard-Foy --- _overviews/core/collections-migration-213.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/core/collections-migration-213.md b/_overviews/core/collections-migration-213.md index 114da1f632..5eb05536ee 100644 --- a/_overviews/core/collections-migration-213.md +++ b/_overviews/core/collections-migration-213.md @@ -16,7 +16,7 @@ The most important changes in the Scala 2.13 collections library are: - The type hierarchy is simplified. `Traversable` no longer exists, only `Iterable`. - The `to[Collection]` method was replaced by the `to(Collection)` method. - The `toC` methods are strict by convention and yield the default collection type where applicable. For example, `Iterator.continually(42).take(10).toSeq` produces a `List[Int]` and without the limit would not. - - `toIterable` is deprecated wherever defined. For `Iterator`, in particular, prefer `to[LazyList]`. + - `toIterable` is deprecated wherever defined. For `Iterator`, in particular, prefer `to(LazyList)`. - Views have been vastly simplified and work reliably now. They no longer extend their corresponding collection type, for example, an `IndexedSeqView` no longer extends `IndexedSeq`. - `collection.breakOut` no longer exists, use `.view` and `.to(Collection)` instead. - Immutable hash sets and hash maps have a new implementation (`ChampHashSet` and `ChampHashMap`, based on the ["CHAMP" encoding](https://michael.steindorfer.name/publications/oopsla15.pdf)). From add60f3231771d2132441cacfc9ec8815f711211 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Wed, 30 Mar 2022 16:26:08 +0200 Subject: [PATCH 1818/3075] final proof read --- _overviews/contribute/add-guides.md | 29 +++---- _overviews/contribute/bug-reporting-guide.md | 13 +-- _overviews/contribute/corelibs.md | 2 +- _overviews/contribute/documentation.md | 6 +- _overviews/contribute/guide.md | 2 +- _overviews/contribute/hacker-guide.md | 81 ++++++++++--------- _overviews/contribute/partest-guide.md | 14 +++- ...cala-standard-library-api-documentation.md | 35 ++++---- 8 files changed, 89 insertions(+), 93 deletions(-) diff --git a/_overviews/contribute/add-guides.md b/_overviews/contribute/add-guides.md index ed8b0d36c7..bbb43a9686 100644 --- a/_overviews/contribute/add-guides.md +++ b/_overviews/contribute/add-guides.md @@ -6,7 +6,7 @@ num: 7 ## Why Contribute New Learning Material? As [Heather Miller writes][why-contribute], contributing to [docs.scala-lang.org][home] is -critical to making Scala accessible to newcomers, experience programmers, and anyone who is curious. +critical to making Scala accessible to newcomers, experienced programmers, and anyone who is curious. It is also a fantastic way to contribute for anyone who is comfortable using Scala, but maybe does not want to get involved with complex tools like the compiler. @@ -45,7 +45,7 @@ To use this feature you must use the backtick notation as documented by mdoc, ## Submitting Docs -For you to contribute a document, first +To contribute a new document, you should first [fork](https://help.github.com/articles/fork-a-repo/) the [repo](https://github.com/scala/docs.scala-lang), then write your article in [Markdown](https://daringfireball.net/projects/markdown/syntax) (example below), and finally submit a pull request. @@ -87,7 +87,7 @@ is provided. The goal of this documentation repository is to be highly curated, rather than the approach by other community-driven documentation platforms, like wikis. Therefore, to be included on [docs.scala-lang.org][home], a document must: -- **"fit in"** to the repository ( _i.e.,_ it should not be a complete duplicate of another article), +- **"fit in"** to the repository (_i.e.,_ it should not be a complete duplicate of another article), - **be polished**, i.e. it must be thorough, complete, correct, and organized; written as an article to be understood by many users. - **be maintained**, if the document might require revisions from time to time, be prepared to keep it up to date, or @@ -100,8 +100,6 @@ clarifications, etc. ## Document Templates -> **Note:** These templates will soon change slightly as a result of necessary refactoring. - ### Guides/Overviews A guide or an overview that can be logically placed on **one** markdown page should be placed in the directory @@ -215,16 +213,14 @@ snippet and ensures that it's valid.
             ```scala mdoc
 val a = 1
-```
-
+```
If you have a snippet that you expect to fail, you can also account for this by using `mdoc:fail` for a compile error `mdoc:crash` for a runtime-error.
```scala mdoc:fail
 val b: String = 3 // won't compile
-```
-
+``` Keep in mind that a single file is all compiled as a single unit, so you can't redefine a variable that was defined above in another code snippet. _However_ @@ -239,28 +235,23 @@ above. Here is an example using the various modifiers. def now() = Instant.now() object Foo {} -``` - +```
```scala mdoc:nest
 case class Foo(a: Int) // conflicts with Foo above, but it's nested so it's fine
-```
-
+```
```scala mdoc
 val a = s"The time is ${now()}" // still have access to the now method from above
-```
-
+```
```scala mdoc:reset
 case class Foo(a: String) // forget the previous Foo's and start fresh
-```
-
+```
```scala mdoc
 val myFoo = Foo("hi") // now we only have access to the last Foo
-```
-
+``` [collections-overview]: {% link _overviews/collections-2.13/introduction.md %} [why-contribute]: {% link contribute.md %} diff --git a/_overviews/contribute/bug-reporting-guide.md b/_overviews/contribute/bug-reporting-guide.md index 91858d589c..6830c18ab9 100644 --- a/_overviews/contribute/bug-reporting-guide.md +++ b/_overviews/contribute/bug-reporting-guide.md @@ -3,7 +3,8 @@ title: Bug Reporting Guide num: 8 --- -The Scala compiler and standard library bug tracker is located at [https://github.com/scala/bug](https://github.com/scala/bug), and for Scala 3, it is located at [github.com/lampepfl/dotty](https://github.com/lampepfl/dotty/issues). Before you submit a bug make sure that it is certainly a bug by following instructions in *Is it a Bug?*. +The Scala compiler and standard library bug tracker is located at [https://github.com/scala/bug](https://github.com/scala/bug), and for Scala 3, it is located at [github.com/lampepfl/dotty](https://github.com/lampepfl/dotty/issues). Before you submit a bug make sure that it is certainly a bug by following instructions +in [Is it a Bug?](#is-it-a-bug). ## Is it a Bug? @@ -11,7 +12,7 @@ The first step in identifying a bug is to identify which component of the Scala - **Library** bugs typically manifest themselves as run-time exceptions, or as *unexpected*/*unintuitive* behavior of Scala Standard Library methods. - **Compiler** errors are manifested as compile time exceptions, unexpected behavior of your code at run time, or invalid behavior of the type system. - - **Reflection** are bugs that appear in the ‘scala.reflect’ package. For the *reflection* bugs , the same rules apply as for the *library* bugs. + - **Reflection** are bugs that appear in the `scala.reflect` package. For the *reflection* bugs, the same rules apply as for the *library* bugs. - **Scaladoc** bugs are manifested as a logical problems in the information it presents (that is, the displayed information is incorrect, such as an incorrect subclassing relationship), or incorrect behavior of the user interface. If you'd like to suggest a change in the content of the documentation, please submit a pull request (possible to do in the browser using GitHub, which is easier and faster than filing a bug). Please file a bug about the content of documentation only if you cannot provide a suggestion for its fix. If your issue is related to any of the following external projects, make sure to use its appropriate issue tracker: @@ -31,13 +32,13 @@ If you have a code snippet that is resulting in bytecode which you believe is be * Make sure you minimize your problem. To correctly minimize the problem follow the following instructions: - 1. Gradually take apart the offensive code snippet until you believe you have the simplest representation of your problem. + 1. Gradually remove parts from the original failing code snippet until you believe you have the simplest representation of your problem. - 2. Ensure that you have decoupled your code snippet from any library that could be introducing the offensive behavior. One way to achieve this is to try to recompile the offensive code snippet in isolation, outside of the context of any complex build environment. If your code depends on some strictly Java library and source code is available for it, make sure that the latter is also minimized. + 2. Ensure that you have decoupled your code snippet from any library that could be introducing the incorrect behavior. One way to achieve this is to try to recompile the offending code snippet in isolation, outside of the context of any complex build environment. If your code depends on some strictly Java library and source code is available for it, make sure that the latter is also minimized. 3. Make sure you are compiling your project from a clean slate. Your problem could be related to separate compilation, which is difficult to detect without a clean build with new `.class` files. - 4. If you have encountered a bug while building your code in the IDE, then please reproduce it on the command line. The same rule applies for build tools like `sbt` or `ant`. + 4. If you have encountered a bug while building your code in the IDE, then please reproduce it on the command line. The same rule applies for build tools like **sbt** or **Mill**. 5. If you want to file an improvement in the issue tracker please discuss it first on one of the mailing lists. They offer much bigger audience than issue tracker. The latter is not suitable for long discussions. @@ -69,7 +70,7 @@ Please make sure to fill in as many fields as possible. Make sure you've indicat 3. **Labels** related to your issue. For example, if you think your issue is related to the typechecker, and if you have successfully minimized your issue, label your bug as "typechecker" and "minimized". Issue tracker will suggest names for existing labels as you type them so try not to create duplicates. 4. **Running environment**. Are you running on Linux? Windows? What JVM version are you using? -In order for us to quickly triage the bug that you've found, it's important that the code snippet which produces the observed issue is as minimized as possible. For advice on minimizing your code snippet, please see the appropriate subsection of the above (Is it a Bug?). +In order for us to quickly triage the bug that you've found, it's important that the code snippet which produces the observed issue is as minimized as possible. For advice on minimizing your code snippet, please see the appropriate subsection of the above ([Is it a Bug?](#is-it-a-bug)). ### Description diff --git a/_overviews/contribute/corelibs.md b/_overviews/contribute/corelibs.md index 1eb2f840b0..4fcab907a2 100644 --- a/_overviews/contribute/corelibs.md +++ b/_overviews/contribute/corelibs.md @@ -14,7 +14,7 @@ There are several options for contributing to Scala's core libraries. You can: ### Significant changes For significant new functionality or a whole new API to be considered for inclusion in the core Scala distribution, -please take into account [https://github.com/scala/scala-dev/issues/661] before doing so. +please take into account [scala/scala-dev#661](https://github.com/scala/scala-dev/issues/661) before doing so. [documentation]: {% link _overviews/contribute/documentation.md %} [bug-reporting-guide]: {% link _overviews/contribute/bug-reporting-guide.md %} diff --git a/_overviews/contribute/documentation.md b/_overviews/contribute/documentation.md index 9bd4597b36..bd93b7fbd3 100644 --- a/_overviews/contribute/documentation.md +++ b/_overviews/contribute/documentation.md @@ -7,10 +7,10 @@ num: 5 There are several ways you can help out with the improvement of Scala documentation. These include: * API Documentation in Scaladoc -* Guides, Overviews, Tutorials, Cheat Sheets and more on the docs.scala-lang.org site -* Updating scala-lang.org +* Guides, Overviews, Tutorials, Cheat Sheets and more on the [docs.scala-lang.org][home] site +* Updating [scala-lang.org](https://scala-lang.org) -Please read this page, and the pages linked from this one, fully before contributing documentation. Many of the questions you have will be answered in these resources. If you have a question that isn't answered, feel free to ask on the [Scala Contributors](https://contributors.scala-lang.org/) mailing list and then, please, submit a pull request with updated documentation reflecting that answer. +Please read this page, and the pages linked from this one, fully before contributing documentation. Many frequently asked questions will be answered in these resources. If you have a question that isn't answered, feel free to ask on the [Scala Contributors](https://contributors.scala-lang.org/) forum and then, please, submit a pull request with updated documentation reflecting that answer. **General requirements** for documentation submissions include spell-checking all written language, ensuring code samples compile and run correctly, correct grammar, and clean formatting/layout of the documentation. diff --git a/_overviews/contribute/guide.md b/_overviews/contribute/guide.md index 472d2d41ab..33330f511d 100644 --- a/_overviews/contribute/guide.md +++ b/_overviews/contribute/guide.md @@ -18,7 +18,7 @@ num: 10 Just to name a few common reasons: * contributing a patch is the best way to make sure your desired changes will be available in the next Scala version -* Scala is written in Scala, so going through the source code and patching it will improve your Scala-fu +* Scala is written in Scala, so going through the source code and patching it will improve your knowledge of Scala. * last but not least, it only takes a few accepted commits to make it into the [Scala Contributor Hall of Fame](https://github.com/scala/scala/contributors). The main Scala project consists of the standard Scala library, the Scala reflection and macros library, diff --git a/_overviews/contribute/hacker-guide.md b/_overviews/contribute/hacker-guide.md index 92181003fa..2a70714f53 100644 --- a/_overviews/contribute/hacker-guide.md +++ b/_overviews/contribute/hacker-guide.md @@ -1,5 +1,5 @@ --- -title: Scala hacker guide +title: Scala 2 Hacker's Guide by: Eugene Burmako num: 12 --- @@ -18,26 +18,27 @@ Though, there's an annoying issue which you occasionally stumble upon: the formatting string interpolator `f` [does not support](https://github.com/scala/bug/issues/6725) new line tokens `%n`. -One approach would be to go the mailing list, request that the bug be fixed, and then to wait indefinitely for the fix arrive. Another approach would be to instead patch Scala oneself, and to submit the fix to the Scala repository in hopes that it might make it into a subsequent release. +One approach would be to go the [Scala 2 bug tracker](https://github.com/scala/bug), request that the bug be fixed, and then to wait indefinitely for the fix arrive. Another approach would be to instead patch Scala yourself, and to submit the fix to the Scala repository in hopes that it might make it into a subsequent release. **_Of note_**: There are several types of releases/builds. Nightly builds are produced every night at a fixed time. Minor releases happen once every few months. Major releases typically happen once per year. ## 1. Connect -Sometimes it's appealing to hack alone and not to have to interact with others out of fear, or out of comfort. However, in the context a big project such as Scala, -this might not be the very best idea. There are people in the Scala community who have spent years accumulating knowledge about Scala libraries and internals. They might provide +Sometimes it's appealing to hack alone and not to have to interact with others. However, in the context a big project such as Scala, there might be better ways. There are people in the Scala community who have spent years accumulating knowledge about Scala libraries and internals. They might provide unique insights and, what's even better, direct assistance in their areas, so it is not only advantageous, but recommended to communicate with the community about your new patch. -Typically bug fixes and new features start out as an idea or an experiment posted on one of [our mailing lists](https://scala-lang.org/community/index.html#forums) to find out how people feel -about things you want to implement. People proficient in certain areas of Scala usually monitor mailing lists, so you'll often get some help -by simply posting a message. But the most efficient way to connect is to cc your message to one of the people responsible for maintaining the aspect of Scala which you wish to contribute to. +Typically bug fixes and new features start out as an idea or an experiment posted on one of [our forums](https://scala-lang.org/community/index.html#forums) to find out how people feel +about things you want to implement. People proficient in certain areas of Scala usually monitor forums and discussion rooms, so you'll often get some help by posting a message. +But the most efficient way to connect is to mention in your message one of the people responsible for maintaining the aspect of Scala which you wish to contribute to. A list of language features/libraries along with their maintainer's full names and GitHub usernames is [in the Scala repo README](https://github.com/scala/scala#get-in-touch). In our running example, since Martin is the person who submitted the string interpolation Scala Improvement Proposal and implemented this language feature for Scala 2.10.0, he might be interested in learning of new bugfixes to that feature. -As alluded to earlier, one must also choose an appropriate mailing list. Typically, one would use the [Scala Contributors](https://contributors.scala-lang.org/) mailing list, as it is devoted to discussions about the core internal design and implementation of the Scala system. However, since this issue has been discussed previously on the scala-user mailing list, -in this example, we post to the [the scala-user mailing list](https://groups.google.com/group/scala-user) about our issue. +As alluded to earlier, one must also choose an appropriate avenue to discuss the issue. Typically, one would use the [Scala Contributor's Forum][contrib-forum], as there are post categories devoted to discussions about the core internal design and implementation of the Scala system. + +In this example, the issue was previously discussed on the (now unused) scala-user mailing list, at the time, +we would have posted to the [the (now unused) scala-user mailing list](https://groups.google.com/group/scala-user) about our issue: Posting to scala-user Response from Martin @@ -86,10 +87,11 @@ Before you start making changes, always create your own branch. Never work on th the changes you plan on making. Use a prefix that describes the nature of your change. There are essentially two kinds of changes: bug fixes and new features. -* For bug fixes, use `issue/NNNN` or `ticket/NNNN` for bug NNNN from the [Scala bug tracker](https://github.com/scala/bug). -* For new feature use `topic/XXX` for feature XXX. Use feature names that make sense in the context of the whole Scala project and not just to you personally. For example, if you work on diagrams in Scaladoc, use `topic/scaladoc-diagrams` instead of just `topic/diagrams` would be a good branch name. +* For bug fixes, use `issue/NNNN` or `ticket/NNNN` for bug `NNNN` from the [Scala bug tracker](https://github.com/scala/bug). +* For new feature use `topic/XXX` for feature `XXX`. Use feature names that make sense in the context of the whole Scala project and not just to you personally. For example, if you work on diagrams in Scaladoc, use `topic/scaladoc-diagrams` instead of just `topic/diagrams` would be a good branch name. -Since in our example, we're going to fix an existing bug [6725](https://github.com/scala/bug/issues/6725), we'll create a branch named `ticket/6725`. +Since in our example, we're going to fix an existing bug +[scala/bug#6725](https://github.com/scala/bug/issues/6725), we'll create a branch named `ticket/6725`. 16:39 ~/Projects/scala (master)$ git checkout -b ticket/6725 Switched to a new branch 'ticket/6725' @@ -102,13 +104,13 @@ The next step after cloning your fork is setting up your machine to build Scala. You need the following tools: -* A Java SDK. The baseline version is 6 for 2.11.x and 8 for 2.12.x. It's possible to use a later SDK for local development, but the continuous integration builds will verify against the baseline version. +* A Java JDK. The baseline version is `8` for 2.13.x and higher. It's possible to use a higher JDK version for local development, but the continuous integration builds will verify against the baseline version. * `sbt`, an interactive build tool commonly used in Scala projects. Acquiring sbt manually is not necessary -- the recommended approach is to download the [sbt-extras runner script](https://github.com/paulp/sbt-extras/blob/master/sbt) and use it in place of `sbt`. The script will download and run the correct version of sbt when run from the Scala repository's root directory. * `curl` -- the build uses `curl` in the `pull-binary-libs.sh` script to download bootstrap libs. -OS X and Linux builds should work. Windows is supported, but it might have issues. Please report to the [Scala bug tracker](https://github.com/scala/bug) if you encounter any. +macOS and Linux builds should work. Windows is supported, but it might have issues. Please report to the [Scala 2 bug tracker](https://github.com/scala/bug) if you encounter any. -Building Scala is as easy as running `sbt dist/mkPack` in the root of your cloned repository. In general, it's much more efficient to enter the `sbt` shell once and run the various tasks from there, instead of running each task by launching `sbt some-task` on your command prompt. +Building Scala can be done with a single command `sbt dist/mkPack`, from the root of your cloned repository. In general, it's much more efficient to enter the `sbt` shell once and run the various tasks from there, instead of running each task by launching `sbt some-task` on your command prompt. Be prepared to wait for a while -- a full "clean" build takes 5+ minutes depending on your machine (longer on older machines with less memory). On a recent laptop, incremental builds usually complete within 10-30 seconds. @@ -116,16 +118,13 @@ Be prepared to wait for a while -- a full "clean" build takes 5+ minutes dependi There's no single editor of choice for working with Scala sources, as there are trade-offs associated with each available tool. -Both Eclipse and IntelliJ IDEA have Scala plugins, which are known to work with our codebase. -Both of those Scala plugins provide navigation, refactoring, error reporting functionality, and integrated debugging. -See [the Scala README](https://github.com/scala/scala#ide-setup) for instructions on using Eclipse and IntelliJ IDEA with the Scala repository. +IntelliJ IDEA has a Scala plugin, which is known to work with our codebase. Alternatively you can use Visual Studio Code with the [Metals IDE extension](https://marketplace.visualstudio.com/items?itemName=scalameta.metals). +Both of these Scala IDE solutions provide navigation, refactoring, error reporting functionality, and integrated debugging. +See [the Scala README](https://github.com/scala/scala#ide-setup) for instructions on using either IntelliJ IDEA or Metals with the Scala repository. -There also exist lighter-weight editors such as Emacs, Sublime or jEdit which are faster and much less memory/compute-intensive to run, while -lacking semantic services and debugging. To address this shortcoming, they can integrate with ENSIME, -a helper program, which hosts a resident Scala compiler providing some of the features implemented in traditional IDEs. However despite -having significantly matured over the last year, support for our particular code base is still being improved, and is not as mature as for Eclipse and IntelliJ. +Other alternative editors exist, such as Atom, Emacs, Sublime Text or jEdit. These are faster and much less memory/compute-intensive to run, but lack semantic services and debugging. -Due to the immense variability in personal preference between IDE/editor experience, it's difficult to recommend a particular tool, and your choice should boil down to your personal preferences. +We recognise that there exist preferences towards specific IDE/editor experiences, so ultimately we recommend that your choice be your personal preference. ## 3. Hack @@ -156,7 +155,7 @@ Now, implement your bugfix or new feature! Here are also some tips & tricks that have proven useful in Scala development: * After building your working copy with the `compile` sbt task, there's no need to leave the comfort of your sbt shell to try it out: the REPL is available as the `scala` task, and you can also run the compiler using the `scalac` task. If you prefer to run the REPL outside sbt, you can generate the scripts in `build/quick/bin` using the `dist/mkQuick` task. -* The sbt workflow is also great for debugging, as you can simply create a remote debugging session in your favorite IDE, and then activate the JVM options for the next time you run the `scala` or `scalac` tasks using: +* The sbt workflow is also great for debugging, as you can create a remote debugging session in your favorite IDE, and then activate the JVM options for the next time you run the `scala` or `scalac` tasks using: ``` > set javaOptions in compiler := List("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8002") @@ -167,9 +166,8 @@ Listening for transport dt_socket at address: 8002 * Also see [the Scala README](https://github.com/scala/scala#incremental-compilation) for tips on speeding up compile times. * If after introducing changes or updating your clone, you get `AbstractMethodError` or other linkage exceptions, try the `clean` task and building again. -* Don't underestimate the power of `print`. When starting with Scala, I spent a lot of time in the debugger trying to figure out how - things work. However later I found out that print-based debugging is often more effective than jumping around. While it might be obvious - to some, I'd like to explicitly mention that it's also useful to print stack traces to understand the flow of execution. When working with `Trees`, you might want to use `showRaw` to get the `AST` representation. +* Don't underestimate the power of using `println` to print debug information. When starting with Scala, I spent a lot of time in the debugger trying to figure out how + things work. However later I found out that print-based debugging is often more effective than jumping around. It's also useful to print stack traces to understand the flow of execution, for example what code executed before some action occurred. When working with `Trees`, you might want to use `showRaw` to get the `AST` representation. * You can publish your newly-built scala version locally using the `publishLocal` task in sbt. * It's convenient to enable the following local settings to speed up your workflow (put these in `local.sbt` in your working copy): @@ -184,33 +182,33 @@ testOptions in IntegrationTest in LocalProject("test") ++= Seq(Tests.Argument("- // antStyle := true ``` -* Adding a macro to the `Predef` object is a pretty involved task. Due to bootstrapping, you cannot just throw a macro into it. For this reason, the process is more involved. You might want to follow the way `StringContext.f` itself is added. In short, you need to define your macro under `src/compiler/scala/tools/reflect/` and provide no implementation in `Predef` (`def fn = macro ???`). Now you have to set up the wiring. Add the name of your macro to `src/reflect/scala/reflect/internal/StdNames.scala`, add the needed links to it to `src/reflect/scala/reflect/internal/Definitions.scala`, and finally specify the bindings in `src/compiler/scala/tools/reflect/FastTrack.scala`. [Here's](https://github.com/folone/scala/commit/59536ea833ca16c985339727baed5d70e577b0fe) an example of adding a macro. +* Adding a macro to the `Predef` object is a pretty involved task. Due to bootstrapping, it makes it more complex to add a macro. For this reason, the process is more involved. It could be useful to replicate the way `StringContext.f` itself is added. In short, you need to define your macro under `src/compiler/scala/tools/reflect/` and provide no implementation in `Predef` (it will look like `def fn = macro ???`). Now you have to set up the wiring. Add the name of your macro to `src/reflect/scala/reflect/internal/StdNames.scala`, add the needed links to it to `src/reflect/scala/reflect/internal/Definitions.scala`, and finally specify the bindings in `src/compiler/scala/tools/reflect/FastTrack.scala`. [Here's](https://github.com/folone/scala/commit/59536ea833ca16c985339727baed5d70e577b0fe) an example of adding a macro. -### Documentation +### Where to Find Documentation -There are several areas that one could contribute to -- there is the Scala library, the Scala compiler, and other tools such as Scaladoc. Each area has varying amounts of documentation. +The separate projects under Scala have varying amounts of documentation: ##### The Scala Library -Contributing to the Scala standard library is about the same as working on one of your own libraries. Beyond the Scala collections hierarchy, there are no complex internals or architectures to have to worry about. Just make sure that you code in a "don't-repeat-yourself" (DRY) style, obeying the "boy scout principle" (i.e. make sure you've left the code cleaner than you found it). +Contributing to the Scala standard library is about the same as working on one of your own libraries. If documentation is necessary for some trait/class/object/method/etc in the Scala standard library, typically maintainers will include inline comments describing their design decisions or rationale for implementing things the way they have, if it is not straightforward. -If you intend on contributing to Scala collections, please make sure you're familiar with the design of the Scala collections library. It can be easy to put an implementation in the wrong location if you are unfamiliar with the collections architecture. There is an excellent and very detailed guide covering [the Architecture of Scala Collections][collections-arch], as well as a larger more general [Scala collections Guide][collections-intro] covering the sequential portion of collections. For parallel collections, there also exists a detailed [Scala Parallel Collections Guide][collections-par]. +The Scala collections framework, part of the Scala standard library, is more complex. You should become familiar +with its architecture, which is documented in [the Architecture of Scala Collections][collections-arch]. +The [Scala Collections Guide][collections-intro] is more general, covering the synchronous portion of collections. For parallel collections, there also exists a detailed [Scala Parallel Collections Guide][collections-par]. ##### The Scala Compiler -Documentation about the internal workings of the Scala compiler is scarce, and most of the knowledge is passed around by email ([Scala Contributors](https://contributors.scala-lang.org/) mailing list), ticket, or word of mouth. However the situation is steadily improving. Here are the resources that might help: +Documentation about the internal workings of the Scala compiler is scarce, and most of the knowledge is passed around by forum ([Scala Contributors](https://contributors.scala-lang.org/) forum), chat-rooms (see `#scala-contributors` on [Discord][discord-contrib]), ticket, or word of mouth. However the situation is steadily improving. Here are the resources that might help: * [Compiler internals videos by Martin Odersky](https://www.scala-lang.org/old/node/598.html) are quite dated, but still very useful. In this three-video - series Martin explains the general architecture of the compiler, and the basics of the front-end, which has recently become Scala reflection API. + series Martin explains the general architecture of the compiler, and the basics of the front-end, which later became the `scala-reflect` module's API. * [Reflection documentation][reflect-overview] describes fundamental data structures (like `Tree`s, `Symbol`s, and `Types`) that - are used to represent Scala programs and operations defined on then. Since much of the compiler has been factored out and made accessible via the Reflection API, all of the fundamentals needed for reflection are the same for the compiler. -* [Reflection and Compilers by Martin Odersky](https://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Reflection-and-Compilers), a talk - at Lang.NEXT 2012 in which Martin elaborates on the design of scalac and the architecture of the reflection API. + are used to represent Scala programs and operations defined on then. Since much of the compiler has been factored out and made accessible via the `scala-reflect` module, all of the fundamentals needed for reflection are the same for the compiler. * [Scala compiler corner](https://lampwww.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/) contains extensive documentation about most of the post-typer phases (i.e. the backend) in the Scala compiler. -* [Scala Contributors](https://contributors.scala-lang.org/), a mailing list which hosts discussions about the core +* [Scala Contributors](https://contributors.scala-lang.org/), a forum which hosts discussions about the core internal design and implementation of the Scala system. ##### Other Projects @@ -303,7 +301,7 @@ Here are some more testing tips: ... Finished: FAILURE -This means your change is backward or forward binary incompatible with the specified version (the check is performed by the [migration manager](https://github.com/typesafehub/migration-manager)). The error message is actually saying what you need to add to `bincompat-backward.whitelist.conf` or `bincompat-forward.whitelist.conf` to make the error go away. If you are getting this on an internal/experimental api, it should be safe to add suggested sections to the config. Otherwise, you might want to target a newer version of scala for this change. +This means your change is backward or forward binary incompatible with the specified version (the check is performed by the [migration manager](https://github.com/typesafehub/migration-manager)). The error message is actually saying what you need to modify `project/MimaFilters.scala` to make the error go away. If you are getting this on an internal/experimental api, it should be safe to add suggested sections to the config. Otherwise, you might want to target a newer version of scala for this change. ### Verify @@ -380,7 +378,10 @@ Note that there can be a gap between a successful review and the merge, because So don't be confused if your reviewer says “LGTM”, but your code doesn't get merged immediately. [collections-arch]: {% link _overviews/core/architecture-of-scala-collections.md %} -[collections-intro]: {% link _overviews/collections/introduction.md %} +[collections-intro]: {% link _overviews/collections-2.13/introduction.md %} [collections-par]: {% link _overviews/parallel-collections/overview.md %} [reflect-overview]: {% link _overviews/reflection/overview.md %} [partest-guide]: {% link _overviews/contribute/partest-guide.md %} +[documentation]: {% link _overviews/contribute/documentation.md %} +[contrib-forum]: https://contributors.scala-lang.org/ +[discord-contrib]: https://discord.com/invite/scala diff --git a/_overviews/contribute/partest-guide.md b/_overviews/contribute/partest-guide.md index c3e6980b06..c8eb5cbf02 100644 --- a/_overviews/contribute/partest-guide.md +++ b/_overviews/contribute/partest-guide.md @@ -9,21 +9,27 @@ Partest is a custom parallel testing tool that we use to run the test suite for The test suite can be run from the sbt console with: - > partest +``` +sbt:root> partest +``` You can get a summary of the usage by running `partest --help`. If you would like to run particular tests pass the test paths as arguments - > partest test/files/pos/bounds.scala test/scaladoc/run/diagrams-base.scala +``` +sbt:root> partest test/files/pos/bounds.scala test/scaladoc/run/diagrams-base.scala +``` To run only the Scaladoc tests use `--srcpath` with the location of the tests - > partest --srcpath scaladoc +``` +sbt:root> partest --srcpath scaladoc +``` ## Using ant -Please note support for ant was removed on the 2.12 branch. +> Please note support for ant was removed on the 2.12 branch. The test suite can be run by using ant from the command line: diff --git a/_overviews/contribute/scala-standard-library-api-documentation.md b/_overviews/contribute/scala-standard-library-api-documentation.md index c1303e8b18..a6c812b7e4 100644 --- a/_overviews/contribute/scala-standard-library-api-documentation.md +++ b/_overviews/contribute/scala-standard-library-api-documentation.md @@ -21,16 +21,14 @@ contribution steps and guidelines. Thank you.* Since API documentation is located in Scala source code files, the process for contributing API documentation is similar to that of contributing bug-fixes to the Scala code base, but without the requirement that there be an issue filed on GitHub -first. When forking/branching, just use a `scaladoc/xxxx` branch name, where xxxx is a +first. When forking/branching, it would help to use a `scaladoc/xxxx` branch name, where `xxxx` is a descriptive, but short branch name (e.g. `scaladoc/future-object`). -However, if an issue *does* exist, please use `issue/NNNN`, where NNNN is the ticket number, +However, if an issue *does* exist, please use `issue/NNNN`, where `NNNN` is the ticket number, instead. -If you would like to assist us by helping us find missing documentation and -submitting bug reports for existing documentation, -[please read the following section](#contribute-api-documentation-bug-reports). -If you want to contribute new API documentation, -[jump down to the next section](#contribute-new-api-documentation). +If you would like to assist us, you can +[report missing/incorrect API documentation](#contribute-api-documentation-bug-reports), or +[contribute new API documentation](#contribute-new-api-documentation). ## Contribute API Documentation Bug Reports @@ -45,8 +43,8 @@ If you find an issue, please log it in the [Scala bug tracker](https://github.co **after making sure it is not already logged as an issue**. To help with disambiguation, please use the following format for issue title: -* Use an action describing the work required. E.g. Add, Document, Correct, Remove -* Use the full package, class/trait/object name (or state package object if +* Use an action describing the work required, e.g. **Add**, **Document**, **Correct**, **Remove**. +* Use the full package, class/trait/object/enum name (or state package object if that is the case). * Extremely short description of what to do. * More detail can (and should) go into the issue description, including a short @@ -60,10 +58,10 @@ Here is an example of the title and description for an example API documentation and the description: -`The methods on the Future companion object are critical` -`for using Futures effectively without blocking. Provide code` -`examples of how methods like sequence, transform, fold and` -`firstCompletedOf should be used.` +> The methods on the `Future` companion object are critical +> for using Futures effectively without blocking. Provide code +> examples of how methods like `sequence`, `transform`, `fold` and +> `firstCompletedOf` should be used. In addition to following these conventions, please add `documentation` and `community` labels to the issue, and put them in the `Documentation and API` @@ -93,9 +91,8 @@ new API documentation to save time, effort, mistakes and repetition. the whole document though, and pay close attention to the title and commit message formats, noting *present tense*, *length limits* and that it must merge cleanly. Remember that the title of the pull request will become the commit - message when merged. **Also**, be sure to assign one or more reviewers to the PR, list of - reviewers is at the bottom of this document, but the quick version is to add - `Review by @heathermiller` or `Review by @dickwall` **in the pull request comments**. + message when merged. **Also**, be sure to assign one or more reviewers to the PR, if this is + not possible for you, you could mention a user in **in the pull request comments**. ### Extra Requirements for Scaladoc Documentation Commits @@ -106,9 +103,9 @@ PR is merged in smoothly: * Any and all code examples provided should *be correct, compile and run* as expected (ensure this in the REPL or your IDE). * Spelling must be checked for all written language *and* code examples where - possible. Most editors have some spell checking feature available. Obviously - Scala code is likely to flag as mis-spelled sometimes, but any written language - should be checked. If you can also use a grammar checker, even better. We + possible. Most editors have some spell checking feature available. Scala code + itself is permitted to not pass a spell-checker, however any written language + should be checked. If you can also use a grammar checker, it will help. We *will* ask for spelling and grammar to be corrected before acceptance. * You **must** also run `sbt doc`, fix any problems and check the formatting and layout of your changes. Again, corrections will be required if formatting or From 8c3c443440ea72588a6bf8f35aeebfcad8ce464c Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Wed, 30 Mar 2022 17:00:52 +0200 Subject: [PATCH 1819/3075] remove contribute from nav bar --- _data/nav-header.yml | 7 ------- _includes/site-header.html | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/_data/nav-header.yml b/_data/nav-header.yml index 03621e6d64..b04b23ca78 100644 --- a/_data/nav-header.yml +++ b/_data/nav-header.yml @@ -1,17 +1,10 @@ - title: Documentation url: "/" - can-highlight: true - title: Download url: https://www.scala-lang.org/download/ - can-highlight: true - title: Community url: https://www.scala-lang.org/community/ - can-highlight: true - title: Libraries url: https://index.scala-lang.org - can-highlight: true -- title: Contribute - url: /contribute/ - title: Blog url: https://www.scala-lang.org/blog/ - can-highlight: true diff --git a/_includes/site-header.html b/_includes/site-header.html index 70f1cb6840..d2583b913f 100644 --- a/_includes/site-header.html +++ b/_includes/site-header.html @@ -10,7 +10,7 @@ From e99b6c664acc165fe48ee8307139c3cebb4a0173 Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Wed, 30 Mar 2022 18:21:18 +0200 Subject: [PATCH 1820/3075] Recommend using the Scala Improvement Process category only instead of cross-posting on two categories. --- _sips/sip-submission.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/_sips/sip-submission.md b/_sips/sip-submission.md index e2efb5ec2a..4d9ae53a40 100644 --- a/_sips/sip-submission.md +++ b/_sips/sip-submission.md @@ -53,11 +53,10 @@ There are four major steps in the SIP process: Before submitting a SIP, it is required that you perform necessary preparations: -Discuss your idea on the [Scala Contributors Page](https://contributors.scala-lang.org/) (currently, we suggest -cross-posting on -[Scala Improvement Process](https://contributors.scala-lang.org/c/sip) and -[Language Design](https://contributors.scala-lang.org/c/language-design). This -may change in the future.) Create a topic that starts with “Pre-SIP” and briefly +Discuss your idea on the [Scala Contributors Page](https://contributors.scala-lang.org/) (we suggest +posting in the category +[Scala Improvement Process](https://contributors.scala-lang.org/c/sip)). +Create a topic that starts with “Pre-SIP” and briefly describe what you would like to change and why you think it’s a good idea. Proposing your ideas on the mailing list is not an optional step. For every From 640c86c471fcaed944350565e9094d90ef1b4a2e Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Thu, 31 Mar 2022 00:53:26 -0700 Subject: [PATCH 1821/3075] Simplify example and minimize diff --- _tour/lower-type-bounds.md | 40 ++++++++++++++------------------------ 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/_tour/lower-type-bounds.md b/_tour/lower-type-bounds.md index 548ffb733b..9f5cd53b89 100644 --- a/_tour/lower-type-bounds.md +++ b/_tour/lower-type-bounds.md @@ -16,42 +16,32 @@ While [upper type bounds](upper-type-bounds.html) limit a type to a subtype of a Here is an example where this is useful: ```scala mdoc:fail -trait Node[+B] { - def prepend(elem: B): Node[B] +trait List[+B] { + def prepend(elem: B): NonEmptyList[B] = NonEmptyList(elem, this) } -case class ListNode[+B](h: B, t: Node[B]) extends Node[B] { - def prepend(elem: B): ListNode[B] = ListNode(elem, this) - def head: B = h - def tail: Node[B] = t -} +case class NonEmptyList[+B](head: B, tail: List[B]) extends List[B] -case class Nil[+B]() extends Node[B] { - def prepend(elem: B): ListNode[B] = ListNode(elem, this) -} +object Nil extends List[Nothing] ``` -This program implements a singly-linked list. `Nil` represents an empty element (i.e. an empty list). `class ListNode` is a node which contains an element of type `B` (`head`) and a reference to the rest of the list (`tail`). The `class Node` and its subtypes are covariant because we have `+B`. +This program implements a singly-linked list. `Nil` represents an empty list with no elements. `class NonEmptyList` is a node which contains an element of type `B` (`head`) and a reference to the rest of the list (`tail`). The `trait List` and its subtypes are covariant because we have `+B`. However, this program does _not_ compile because the parameter `elem` in `prepend` is of type `B`, which we declared *co*variant. This doesn't work because functions are *contra*variant in their parameter types and *co*variant in their result types. To fix this, we need to flip the variance of the type of the parameter `elem` in `prepend`. We do this by introducing a new type parameter `U` that has `B` as a lower type bound. ```scala mdoc -trait Node[+B] { - def prepend[U >: B](elem: U): Node[U] +trait List[+B] { + def prepend[U >: B](elem: U): NonEmptyList[U] = NonEmptyList(elem, this) } -case class ListNode[+B](head: B, tail: Node[B]) extends Node[B] { - def prepend[U >: B](elem: U): ListNode[U] = ListNode(elem, this) -} +case class NonEmptyList[+B](head: B, tail: List[B]) extends List[B] -object Nil extends Node[Nothing] { - def prepend[U >: Nothing](elem: U): ListNode[U] = ListNode(elem, this) -} +object Nil extends List[Nothing] ``` -We have also simplified `ListNode` to leverage its `case class` fields, and `Nil` to be a singleton object; it is a "node of nothing" because it does not hold an element. The type parameter for `Node` is `B` to suggest we want to store birds at each node. +The type parameter for `List` is `B` to suggest we want to keep lists of birds. Now we can do the following: ```scala mdoc @@ -59,11 +49,11 @@ trait Bird case class AfricanSwallow() extends Bird case class EuropeanSwallow() extends Bird -val africanSwallows: Node[AfricanSwallow] = ListNode[AfricanSwallow](AfricanSwallow(), Nil) -val swallowsFromAntarctica: Node[Bird] = Nil +val africanSwallows: List[AfricanSwallow] = Nil.prepend(AfricanSwallow()) +val swallowsFromAntarctica: List[Bird] = Nil // assign swallows to birds -val birds: Node[Bird] = africanSwallows +val birds: List[Bird] = africanSwallows // add a swallow to birds val moreBirds = birds.prepend(EuropeanSwallow()) @@ -71,11 +61,11 @@ val moreBirds = birds.prepend(EuropeanSwallow()) // add disparate swallows together to get birds val allBirds = africanSwallows.prepend(EuropeanSwallow()) -// but this is a mistake! adding a Node to birds widens the type arg too much. -Xlint will warn! +// but this is a mistake! adding a list of birds widens the type arg too much. -Xlint will warn! val error = moreBirds.prepend(swallowsFromAntarctica) ``` The covariant type parameter allows `birds` to get the value of `africanSwallows`. -The type bound on the type parameter for `prepend` allows adding different varieties of swallows and getting a wider type: instead of `Node[AfricanSwallow]`, we get a `Node[Bird]`. +The type bound on the type parameter for `prepend` allows adding different varieties of swallows and getting a wider type: instead of `List[AfricanSwallow]`, we get a `List[Bird]`. The canary in the coal mine is `-Xlint`, which will warn if the type arg is widened too much. From 0bd08091e2cbccdd3d1f9fdeaa49911ba14fdcaa Mon Sep 17 00:00:00 2001 From: Andrea Mucciarelli Date: Thu, 31 Mar 2022 09:56:08 +0200 Subject: [PATCH 1822/3075] Getting started - sbt track - italian translations (#2239) Co-authored-by: Dale Wijnand --- ...-with-scala-and-sbt-on-the-command-line.md | 79 ++++++++++++++ ...ting-scala-with-sbt-on-the-command-line.md | 101 ++++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 _it/getting-started/sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md create mode 100644 _it/getting-started/sbt-track/testing-scala-with-sbt-on-the-command-line.md diff --git a/_it/getting-started/sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md b/_it/getting-started/sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md new file mode 100644 index 0000000000..0de0347ca5 --- /dev/null +++ b/_it/getting-started/sbt-track/getting-started-with-scala-and-sbt-on-the-command-line.md @@ -0,0 +1,79 @@ +--- +title: Primi passi su scala e sbt con la linea di comando +layout: singlepage-overview +partof: getting-started-with-scala-and-sbt-on-the-command-line +language: it +disqus: true +next-page: /it/testing-scala-with-sbt-on-the-command-line +--- + +In questo tutorial si vedrà come creare un progetto Scala a partire da un template, che può essere usato come punto di partenza anche per progettti personali. +Lo strumento utilizzato per tale scopo è [sbt](https://www.scala-sbt.org/1.x/docs/index.html), che è lo standard di build per Scala. +sbt permette di compilare, eseguire e testare i tuoi progetti, ma permette di svolgere anche altri compiti. +Si presuppone una conoscenza dell'uso della linea di comando. + +## Installazione +1. Assicurarsi di avere la Java 8 JDK (conosciuta anche come 1.8) installata + * Per verificarlo, eseguire `javac -version` da linea di comando e controllare che nell'output sia riportato + `javac 1.8.___` + * Se non si possiede la versione 1.8 o superiore, installarla seguendo [queste indicazioni](https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) +1. Installare sbt + * [Mac](https://www.scala-sbt.org/1.x/docs/Installing-sbt-on-Mac.html) + * [Windows](https://www.scala-sbt.org/1.x/docs/Installing-sbt-on-Windows.html) + * [Linux](https://www.scala-sbt.org/1.x/docs/Installing-sbt-on-Linux.html) + +## Creare il progetto +1. Eseguire il comando `cd` specificando una cartella vuota per spostarsi in essa. +1. Eseguire il comando `sbt new scala/hello-world.g8`. Questo effettuerà una pull del template 'hello-world' da GitHub. + Si occuperà inoltre di creare la cartella `target`, che per ora può essere ignorata. +1. Quando richiesto verrà richiesto il nome dell'applicazione, indicare `hello-world`. In questo modo verrà creato un progetto chiamato "hello-world". +1. Osserviamo cosa è stato generato una volta eseguiti i passaggi sopra riportati: + +``` +- hello-world + - project (sbt usa questa cartella per installare e gestire plugins e dipendenze) + - build.properties + - src + - main + - scala (Tutto il codice scala che viene scritto dovrà andare qui) + - Main.scala (Entry point dell'applicazione) <-- per ora è tutto ciò che ci servirà + - build.sbt (il file di definizione della build interpretato da sbt) +``` + +Una volta che verrà buildato il progetto, sbt creerà diverse cartelle `target` per i file generati. Possono essere ignorate per lo scopo di questo tutorial. + +## Eseguire il progetto +1. `cd` nella cartella `hello-world`. +1. Lanciare il comando `sbt`. Questo aprirà la console di sbt. +1. Eseguire `~run`. Il carattere `~` è opzionale. Indica ad sbt di eseguirsi ad ogni salvataggio di un file, permettendo un ciclo di modifica, esecuzione e debug più veloce. sbt genererà anche una cartella chiamata `target` che può essere ignorata. + +## Modificare il codice +1. Aprire il file `src/main/scala/Main.scala` in un qualsiasi editor di testo. +1. Modificare "Hello, World!" in "Hello, New York!" +1. Se non è stato interrotto il comando sbt, dovrebbe ora apparire "Hello, New York!" sulla console. +1. Si può continuare a modificare il file, e le modifiche dovrebbero apparire a schermo se non vengono riportati errori. + +## Aggiungere una dipendenza +Vediamo ora come utilizzare librerie pubblicate da terzi per aggiungere ulteriori funzionalità alle nostre applicazioni. + +1. Aprire il file `build.sbt` con un qualsiasi editor di testo e aggiungere la seguente riga: + +``` +libraryDependencies += "org.scala-lang.modules" %% "scala-parser-combinators" % "1.1.2" +``` +`libraryDependencies` è un set (un tipo di collection in scala), e utilizzando il simbolo `+=`, +si sta aggiungendo la dipendenza [scala-parser-combinators](https://github.com/scala/scala-parser-combinators) al set di dipendenze che sbt fetcherà quando verà inizializzato. +Una volta eseguito questo passaggio, sarà possibile importare classi, object ed altro da scala-parser-combinators tramite una semplice istruzione di import. + +Ulteriori librerie pubblicate possono essere trovate sul sito +[Scaladex](https://index.scala-lang.org/), dove è possibile copiare le informazioni delle dipendenze cercate nel file `build.sbt`. + +## Next steps + +Si consiglia di continuare al tutorial successivo della serie _getting started with sbt_ , ed imparare a [testare il codice Scala con sbt tramite linea di comando](testing-scala-with-sbt-on-the-command-line.html). + +**oppure** + +- Continuare ad imparare Scala online e in maniera interattiva su + [Scala Exercises](https://www.scala-exercises.org/scala_tutorial). +- Imparare le feature di Scala tramite articoli più concisi su [Tour of Scala]({{ site.baseurl }}/tour/tour-of-scala.html). \ No newline at end of file diff --git a/_it/getting-started/sbt-track/testing-scala-with-sbt-on-the-command-line.md b/_it/getting-started/sbt-track/testing-scala-with-sbt-on-the-command-line.md new file mode 100644 index 0000000000..cac6f0953a --- /dev/null +++ b/_it/getting-started/sbt-track/testing-scala-with-sbt-on-the-command-line.md @@ -0,0 +1,101 @@ +--- +title: Testare scala con sbt da linea di comando +layout: singlepage-overview +partof: testing-scala-with-sbt-on-the-command-line +language: it +disqus: true +previous-page: /it/getting-started-with-scala-and-sbt-on-the-command-line +--- + +Ci sono diverse librerie e modalità per testare il codice Scala, ma in questo tutorial verrà mostrato come eseguire il testing usando [AnyFunSuite](https://www.scalatest.org/scaladoc/3.2.2/org/scalatest/funsuite/AnyFunSuite.html) del framework ScalaTest. +Si assume che si sappia [creare un progetto Scala con sbt](getting-started-with-scala-and-sbt-on-the-command-line.html). + +## Setup +1. Da linea di comando, creare una nuova directory in una posizione a propria scelta. +1. `cd` nella cartella appena creata ed eseguire `sbt new scala/scalatest-example.g8` +1. Quando richiesto, rinominare il progetto come `ScalaTestTutorial`. +1. Il progetto avrà già in se la libreria ScalaTest come dipendenza indicata nel file `build.sbt`. +1. `cd` nel progetto ed eseguire `sbt test`. Questo eseguirà la test suite +`CubeCalculatorTest` con un unico test chiamato `CubeCalculator.cube`. + +``` +sbt test +[info] Loading global plugins from /Users/username/.sbt/0.13/plugins +[info] Loading project definition from /Users/username/workspace/sandbox/my-something-project/project +[info] Set current project to scalatest-example (in build file:/Users/username/workspace/sandbox/my-something-project/) +[info] CubeCalculatorTest: +[info] - CubeCalculator.cube +[info] Run completed in 267 milliseconds. +[info] Total number of tests run: 1 +[info] Suites: completed 1, aborted 0 +[info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0 +[info] All tests passed. +[success] Total time: 1 s, completed Feb 2, 2017 7:37:31 PM +``` + +## Comprendere i test +1. In qualsiasi editor di testo aprire i seguenti due file: + * `src/main/scala/CubeCalculator.scala` + * `src/test/scala/CubeCalculatorTest.scala` +1. Nel file `CubeCalculator.scala`, è riportata la definizione della funzione `cube`. +1. Nel file `CubeCalculatorTest.scala`, è presente una classe chiamata allo stesso modo dell'oggetto che stiamo testando. + +``` + import org.scalatest.funsuite.AnyFunSuite + + class CubeCalculatorTest extends AnyFunSuite { + test("CubeCalculator.cube") { + assert(CubeCalculator.cube(3) === 27) + } + } +``` + +Analizziamo ogni riga di codice. + +* `class CubeCalculatorTest` significa che stiamo testando l'oggetto `CubeCalculator` +* `extends AnyFunSuite` ci permette di utilizzare la funzionalità della classe AnyFunSuite, come ad esempio la funzione `test` +* `test` è una funzione proveniente da AnyFunSuite che raccoglie i risultati delle asserzioni all'interno del corpo della funzione. +* `"CubeCalculator.cube"` è il nome del test. Può essere chiamato in qualsiasi modo, ma la convenzione è "NomeClasse.nomeMetodo". +* `assert` prende una condizione booleana e stabilisce se il test è superato o no. +* `CubeCalculator.cube(3) === 27` controlla se l'output della funzione `cube` sia realmente 27. +Il simbolo `===` è parte di ScalaTest e restituisce messaggi di errore comprensibili. + +## Aggiungere un altro test case +1. Aggiungere un altro blocco di testo contenente il proprio enunciato `assert` che verificherà il cubo di `0`. + + ``` + import org.scalatest.funsuite.AnyFunSuite + + class CubeCalculatorTest extends AnyFunSuite { + test("CubeCalculator.cube 3 should be 27") { + assert(CubeCalculator.cube(3) === 27) + } + + test("CubeCalculator.cube 0 should be 0") { + assert(CubeCalculator.cube(0) === 0) + } + } + ``` + +1. Lanciare `sbt test` nuovamente e controllare i risultati. + + ``` + sbt test + [info] Loading project definition from C:\projects\scalaPlayground\scalatestpractice\project + [info] Loading settings for project root from build.sbt ... + [info] Set current project to scalatest-example (in build file:/C:/projects/scalaPlayground/scalatestpractice/) + [info] Compiling 1 Scala source to C:\projects\scalaPlayground\scalatestpractice\target\scala-2.13\test-classes ... + [info] CubeCalculatorTest: + [info] - CubeCalculator.cube 3 should be 27 + [info] - CubeCalculator.cube 0 should be 0 + [info] Run completed in 257 milliseconds. + [info] Total number of tests run: 2 + [info] Suites: completed 1, aborted 0 + [info] Tests: succeeded 2, failed 0, canceled 0, ignored 0, pending 0 + [info] All tests passed. + [success] Total time: 3 s, completed Dec 4, 2019 10:34:04 PM + ``` + +## Conclusioni +In questo tutorial è stato mostrato una delle modalità per testare il codice Scala. Per saperne di più su FunSuite si può consultare [il sito ufficiale](https://www.scalatest.org/getting_started_with_fun_suite). +Si possono anche consultare altri framework di testing come [ScalaCheck](https://www.scalacheck.org/) e [Specs2](https://etorreborre.github.io/specs2/). From 100ba0eb73d497874afc0e7c3c3a07c2b9405e4e Mon Sep 17 00:00:00 2001 From: Ondrej Lhotak Date: Thu, 31 Mar 2022 11:07:03 +0200 Subject: [PATCH 1823/3075] add instructions for viewing contents of .tasty files to Tasty Overview --- scala3/guides/tasty-overview.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scala3/guides/tasty-overview.md b/scala3/guides/tasty-overview.md index 11d0fa3608..1bf643bebd 100644 --- a/scala3/guides/tasty-overview.md +++ b/scala3/guides/tasty-overview.md @@ -52,6 +52,13 @@ $ scalac | Hello.scala | -> | Hello.tasty | -> | Hello.class | information) ``` +You can view the contents of a _.tasty_ file in a human-readable form by running the compiler on it with the `-print-tasty` flag. +You can also view the contents decompiled in a form similar to Scala source code using the `-decompile` flag. +```bash +$ scalac -print-tasty hello.tasty +$ scalac -decompile hello.tasty +``` + ### The issue with _.class_ files Because of issues such as [type erasure][erasure], _.class_ files are actually an incomplete representation of your code. From 6d41790cd92819c3f645342eb8bfd5d779294032 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Thu, 31 Mar 2022 11:30:57 +0200 Subject: [PATCH 1824/3075] Add scastie, rename top links --- _data/nav-header.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/_data/nav-header.yml b/_data/nav-header.yml index b04b23ca78..eeaa88291c 100644 --- a/_data/nav-header.yml +++ b/_data/nav-header.yml @@ -1,10 +1,12 @@ -- title: Documentation +- title: Learn url: "/" -- title: Download +- title: Install url: https://www.scala-lang.org/download/ +- title: Playground + url: https://scastie.scala-lang.org +- title: Find A Library + url: https://index.scala-lang.org - title: Community url: https://www.scala-lang.org/community/ -- title: Libraries - url: https://index.scala-lang.org - title: Blog url: https://www.scala-lang.org/blog/ From f69fb47e4ad56bc419efbcb6ca8739555728635a Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Thu, 31 Mar 2022 04:34:41 -0700 Subject: [PATCH 1825/3075] Normalize type param and add clarity per review --- _tour/lower-type-bounds.md | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/_tour/lower-type-bounds.md b/_tour/lower-type-bounds.md index 9f5cd53b89..f4191b425b 100644 --- a/_tour/lower-type-bounds.md +++ b/_tour/lower-type-bounds.md @@ -16,33 +16,30 @@ While [upper type bounds](upper-type-bounds.html) limit a type to a subtype of a Here is an example where this is useful: ```scala mdoc:fail -trait List[+B] { - def prepend(elem: B): NonEmptyList[B] = NonEmptyList(elem, this) +trait List[+A] { + def prepend(elem: A): NonEmptyList[A] = NonEmptyList(elem, this) } -case class NonEmptyList[+B](head: B, tail: List[B]) extends List[B] +case class NonEmptyList[+A](head: A, tail: List[A]) extends List[A] object Nil extends List[Nothing] ``` -This program implements a singly-linked list. `Nil` represents an empty list with no elements. `class NonEmptyList` is a node which contains an element of type `B` (`head`) and a reference to the rest of the list (`tail`). The `trait List` and its subtypes are covariant because we have `+B`. +This program implements a singly-linked list. `Nil` represents an empty list with no elements. `class NonEmptyList` is a node which contains an element of type `A` (`head`) and a reference to the rest of the list (`tail`). The `trait List` and its subtypes are covariant because we have `+A`. -However, this program does _not_ compile because the parameter `elem` in `prepend` is of type `B`, which we declared *co*variant. This doesn't work because functions are *contra*variant in their parameter types and *co*variant in their result types. +However, this program does _not_ compile because the parameter `elem` in `prepend` is of type `A`, which we declared *co*variant. This doesn't work because functions are *contra*variant in their parameter types and *co*variant in their result types. -To fix this, we need to flip the variance of the type of the parameter `elem` in `prepend`. We do this by introducing a new type parameter `U` that has `B` as a lower type bound. +To fix this, we need to flip the variance of the type of the parameter `elem` in `prepend`. We do this by introducing a new type parameter `B` that has `A` as a lower type bound. ```scala mdoc -trait List[+B] { - def prepend[U >: B](elem: U): NonEmptyList[U] = NonEmptyList(elem, this) +trait List[+A] { + def prepend[B >: A](elem: B): NonEmptyList[B] = NonEmptyList(elem, this) } -case class NonEmptyList[+B](head: B, tail: List[B]) extends List[B] +case class NonEmptyList[+A](head: A, tail: List[A]) extends List[A] object Nil extends List[Nothing] ``` - -The type parameter for `List` is `B` to suggest we want to keep lists of birds. - Now we can do the following: ```scala mdoc trait Bird @@ -51,21 +48,25 @@ case class EuropeanSwallow() extends Bird val africanSwallows: List[AfricanSwallow] = Nil.prepend(AfricanSwallow()) val swallowsFromAntarctica: List[Bird] = Nil +val someBird: Bird = EuropeanSwallow() // assign swallows to birds val birds: List[Bird] = africanSwallows +// add some bird to swallows, `B` is `Bird` +val someBirds = africanSwallows.prepend(someBird) + // add a swallow to birds val moreBirds = birds.prepend(EuropeanSwallow()) -// add disparate swallows together to get birds +// add disparate swallows together, `B` is `Bird` because that is the supertype common to both swallows val allBirds = africanSwallows.prepend(EuropeanSwallow()) // but this is a mistake! adding a list of birds widens the type arg too much. -Xlint will warn! -val error = moreBirds.prepend(swallowsFromAntarctica) +val error = moreBirds.prepend(swallowsFromAntarctica) // List[Object] ``` The covariant type parameter allows `birds` to get the value of `africanSwallows`. The type bound on the type parameter for `prepend` allows adding different varieties of swallows and getting a wider type: instead of `List[AfricanSwallow]`, we get a `List[Bird]`. -The canary in the coal mine is `-Xlint`, which will warn if the type arg is widened too much. +Use `-Xlint` to warn if the inferred type arg is widened too much. From 9821a64394baf44857099a69a95dca605b7e1ad3 Mon Sep 17 00:00:00 2001 From: Lixiang Ao Date: Fri, 1 Apr 2022 15:18:59 -0700 Subject: [PATCH 1826/3075] Remove deprecated methods As of 2.13.4, the following methods have been deprecated: - append(elems: A*): ArrayBuffer.this.type - prepend(elems: A*): ArrayBuffer.this.type - trimStart(n: Int): Unit - trimEnd(n: Int): Unit Affected examples are updated in this pr. --- _overviews/scala-book/arraybuffer-examples.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/_overviews/scala-book/arraybuffer-examples.md b/_overviews/scala-book/arraybuffer-examples.md index 8d4dd8ef53..381b593e49 100644 --- a/_overviews/scala-book/arraybuffer-examples.md +++ b/_overviews/scala-book/arraybuffer-examples.md @@ -114,24 +114,22 @@ As a brief overview, here are several methods you can use with an `ArrayBuffer`: ```scala val a = ArrayBuffer(1, 2, 3) // ArrayBuffer(1, 2, 3) a.append(4) // ArrayBuffer(1, 2, 3, 4) -a.append(5, 6) // ArrayBuffer(1, 2, 3, 4, 5, 6) -a.appendAll(Seq(7,8)) // ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8) +a.appendAll(Seq(5, 6)) // ArrayBuffer(1, 2, 3, 4, 5, 6) a.clear // ArrayBuffer() val a = ArrayBuffer(9, 10) // ArrayBuffer(9, 10) a.insert(0, 8) // ArrayBuffer(8, 9, 10) a.insertAll(0, Vector(4, 5, 6, 7)) // ArrayBuffer(4, 5, 6, 7, 8, 9, 10) a.prepend(3) // ArrayBuffer(3, 4, 5, 6, 7, 8, 9, 10) -a.prepend(1, 2) // ArrayBuffer(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) -a.prependAll(Array(0)) // ArrayBuffer(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) +a.prependAll(Array(0, 1, 2)) // ArrayBuffer(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) val a = ArrayBuffer.range('a', 'h') // ArrayBuffer(a, b, c, d, e, f, g) a.remove(0) // ArrayBuffer(b, c, d, e, f, g) a.remove(2, 3) // ArrayBuffer(b, c, g) val a = ArrayBuffer.range('a', 'h') // ArrayBuffer(a, b, c, d, e, f, g) -a.trimStart(2) // ArrayBuffer(c, d, e, f, g) -a.trimEnd(2) // ArrayBuffer(c, d, e) +a.dropInPlace(2) // ArrayBuffer(c, d, e, f, g) +a.dropRightInPlace(2) // ArrayBuffer(c, d, e) ``` From f7afc59478816fbfaf4c1991d22fc4d1f900daa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Krenski?= Date: Sun, 3 Apr 2022 18:39:02 +0200 Subject: [PATCH 1827/3075] Fix 2.13 -Xsource:3 flag in incompatibility table --- _overviews/scala3-migration/incompatibility-table.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-migration/incompatibility-table.md b/_overviews/scala3-migration/incompatibility-table.md index 36e156a868..e699addbfe 100644 --- a/_overviews/scala3-migration/incompatibility-table.md +++ b/_overviews/scala3-migration/incompatibility-table.md @@ -19,7 +19,7 @@ Each incompatibility is described by: - The existence of a Scalafix rule that can fix it > #### Scala 2.13 deprecations and feature warnings -> Run the 2.13 compilation with `-source:3` to locate those incompatibilities in the code. +> Run the 2.13 compilation with `-Xsource:3` to locate those incompatibilities in the code. > #### Scala 3 migration versus Scalafix rewrites > The Scala 3 migration mode comes out-of-the-box. From a9de797f1d0cc5957221d13406038606a28cdd65 Mon Sep 17 00:00:00 2001 From: Florian CUNY Date: Mon, 4 Apr 2022 15:05:55 +0200 Subject: [PATCH 1828/3075] fixed typo --- _overviews/scala-book/pure-functions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala-book/pure-functions.md b/_overviews/scala-book/pure-functions.md index e753d67ce4..97c6ef6fb9 100644 --- a/_overviews/scala-book/pure-functions.md +++ b/_overviews/scala-book/pure-functions.md @@ -49,7 +49,7 @@ Conversely, the following functions are *impure* because they violate the defini The `foreach` method on collections classes is impure because it’s only used for its side effects, such as printing to STDOUT. ->A great hint that `foreach` is impure is that it’s method signature declares that it returns the type `Unit`. Because it returns nothing, logically the only reason you ever call it is to achieve some side effect. Similarly, *any* method that returns `Unit` is going to be an impure function. +>A great hint that `foreach` is impure is that its method signature declares that it returns the type `Unit`. Because it returns nothing, logically the only reason you ever call it is to achieve some side effect. Similarly, *any* method that returns `Unit` is going to be an impure function. Date and time related methods like `getDayOfWeek`, `getHour`, and `getMinute` are all impure because their output depends on something other than their input parameters. Their results rely on some form of hidden I/O, *hidden input* in these examples. From 180b9088915462d575813bc2644e598fb2f00348 Mon Sep 17 00:00:00 2001 From: Jason Pickens Date: Wed, 6 Apr 2022 08:02:06 +1200 Subject: [PATCH 1829/3075] Remove strikethrough from rewrite steps example (#2356) --- _overviews/scala3-migration/tooling-syntax-rewriting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-migration/tooling-syntax-rewriting.md b/_overviews/scala3-migration/tooling-syntax-rewriting.md index 976e3c097e..bbe246aa1e 100644 --- a/_overviews/scala3-migration/tooling-syntax-rewriting.md +++ b/_overviews/scala3-migration/tooling-syntax-rewriting.md @@ -86,7 +86,7 @@ We will be able to move it to new syntax automatically in two steps: first by us > The `-indent` option does not work on the classic control structures. > So make sure to run the two steps in the correct order. -> Unfortunately, the compiler is not able to apply both steps at the same time: `-indent -new-syntax -rewrite`. +> Unfortunately, the compiler is not able to apply both steps at the same time: `-indent -new-syntax -rewrite`. ### New Control Structures From 3841483fd8a4c2e64fc021db1eca8d42a264f0ff Mon Sep 17 00:00:00 2001 From: Artem Korsakov Date: Sat, 9 Apr 2022 10:26:48 +0300 Subject: [PATCH 1830/3075] Fix error in `given` definition We can see in the [reference](https://docs.scala-lang.org/scala3/reference/contextual/givens.html) that the right `given` definition is: ``` given intMonthConverter: MonthConverter[Int] with ``` --- _overviews/scala3-book/packaging-imports.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/_overviews/scala3-book/packaging-imports.md b/_overviews/scala3-book/packaging-imports.md index 07450f72f8..3ae2e7c318 100644 --- a/_overviews/scala3-book/packaging-imports.md +++ b/_overviews/scala3-book/packaging-imports.md @@ -354,20 +354,19 @@ object MonthConversions: trait MonthConverter[A]: def convert(a: A): String - given intMonthConverter as MonthConverter[Int]: + given intMonthConverter: MonthConverter[Int] with def convert(i: Int): String = i match case 1 => "January" case 2 => "February" // more cases here ... - given stringMonthConverter as MonthConverter[String]: + given stringMonthConverter: MonthConverter[String] with def convert(s: String): String = s match case "jan" => "January" case "feb" => "February" // more cases here ... -} ``` To import those givens into the current scope, use these two `import` statements: From 519639583aa576680692632a85d94cf1b4118ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=A6=E5=A2=83=E8=BF=B7=E7=A6=BB?= Date: Mon, 11 Apr 2022 20:13:10 +0800 Subject: [PATCH 1831/3075] add zn-cn --- _zh-cn/scala3/new-in-scala3.md | 128 +++++++++++++++++++++++++++++++++ scala3/new-in-scala3.md | 2 +- 2 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 _zh-cn/scala3/new-in-scala3.md diff --git a/_zh-cn/scala3/new-in-scala3.md b/_zh-cn/scala3/new-in-scala3.md new file mode 100644 index 0000000000..28b458c8d5 --- /dev/null +++ b/_zh-cn/scala3/new-in-scala3.md @@ -0,0 +1,128 @@ +--- +layout: singlepage-overview +title: New in Scala 3 +scala3: true +--- + +令人振奋的新版 Scala 3 带来了许多改进和新功能。在这里,我们为你提供最重要的变更的快速概述。如果你想深入挖掘,还有一些参考资料供你使用。 + +- [Scala 3 Book]({% link _overviews/scala3-book/introduction.md %}) 面向刚接触 Scala 语言的开发人员。 +- [Syntax Summary][syntax-summary] 为您提供了新语法的正式描述。 +- [Language Reference][reference] 对 Scala 2 到 Scala 3 的变化做了详细说明。 +- [Migration Guide][migration] 为你提供了从 Scala 2 迁移到 Scala 3 的所有必要信息。 +- [Scala 3 Contributing Guide][contribution] Scala 3 贡献指南,更深入地探讨了编译器,包括修复问题的指南。 + +## What's new in Scala 3 +Scala 3 是对 Scala 语言的一次彻底改造。在其核心部分,类型系统的许多方面都被改变了,变得更有原则性。虽然这也带来了令人兴奋的新功能(比如联合类型),但首先意味着类型系统变得(甚至)不那么碍事了,例如[类型推断][type-inference]和 overload resolution 都得到了很大的改善。 + +### 新的和闪亮的:语法 + +除了许多(小的)清理,Scala 3 的语法还提供了以下改进: + +- 用于控制结构的新“quiet”语法,如 `if`、`while` 和 `for` 。 ([new control syntax][syntax-control]) +- `new` 关键字是可选的 (_aka_ [creator applications][creator]) +- [Optional braces][syntax-indentation]:可选的大括号,支持不受干扰、缩进敏感的编程风格 +- [类型级通配符][syntax-wildcard] 从 `_` 更改为 `?`。 +- implicit(和它们的语法)已被[大量修订][implicits]。 + +### Opinionated: Contextual Abstractions +Scala的一个基本核心概念是(在某种程度上仍然是)为用户提供一小部分强大的功能,这些功能可以被组合成巨大的(有时甚至是不可预见的)表达能力。例如,_implicit_ 的特性被用来模拟上下文抽象、表达类型级计算、模拟类型类、执行隐式强制、编码扩展方法等等。从这些用例中学习,Scala 3 采取了一种略微不同的方法,专注于 __意图__ 而非 __机制__。Scala 3 没有提供一个非常强大的功能,而是提供了多个定制的语言功能,让程序员直接表达他们的意图。 + +- **Abtracting over contextual information**. [Using clauses][contextual-using] 允许程序员对调用上下文中的信息进行抽象,这些信息应该以隐式方式传递。作为对 Scala 2 implicits 的改进,可以按类型指定`using`子句,从而将函数签名从从未显式引用的术语变量名中解放出来。 + +- **Providing Type-class instances**. [Given instances][contextual-givens] 允许程序员定义某个类型的 _规范值_ 。这使得使用类型类的编程更加简单,而不会泄露实现细节。 + +- **Retroactively extending classes**. 在 Scala 2 中,扩展方法必须使用隐式转换或隐式类进行编码。相比之下,在 Scala 3 中,[extension methods][contextual-extension]现在直接内置于语言中,从而产生更好的错误消息和改进的类型推断。 + +- **Viewing one type as another**. 隐式转换已经被重新[设计][contextual-conversions]为类型类转`Conversion`的实例。 + +- **Higher-order contextual abstractions**. [context functions][contextual-functions]的 _全新_ 功能使上下文抽象成为一流的公民。它们是库作者的一个重要工具,允许表达简洁的特定领域语言。 + +- **Actionable feedback from the compiler**. 如果一个隐式参数不能被编译器解决,它现在提供了可能解决这个问题的[import suggestions](https://www.scala-lang.org/blog/2020/05/05/scala-3-import-suggestions.html)。 + +### Say What You Mean: 类型系统改进 +除了极大地改进了类型推断,Scala 3 类型系统还提供了许多新的功能,还为你提供了强大的工具来静态地表达类型中的不变量。 + +- **Enumerations**. [枚举][enums]已经被重新设计,以便与样例类很好地融合,并形成表达[代数数据类型][enums-adts]的新标准。 + +- **Opaque Types**. 将实现细节隐藏在[opaque type aliases][types-opaque]的别名后面,而不需要在性能上付出代价! Opaque types 取代了值类,并允许你建立一个抽象的屏障,而不会造成额外的装箱开销。 + +- **Intersection and union types**. 将类型系统建立在新的基础上,导致了新的类型系统功能的引入:[intersection types][types-intersection]的实例,如`A & B`,既是`A`的实例,也是`B`的实例;[union types][types-union]的实例,如`A | B`,是`A`或`B`的实例。这两种结构都允许程序员在继承层次结构之外灵活地表达类型约束。 + +- **Dependent function types**. Scala 2 已经允许返回类型依赖于(值)参数。在 Scala 3 中,现在可以对这种模式进行抽象,表达[dependent function types][types-dependent]。在类型`F = (e: Entry) => e.Key`中,结果类型取决于参数。 + +- **Polymorphic function types**. 与 dependent function types 一样,Scala 2 支持拥有类型参数的方法,但不允许程序员对这些方法进行抽象。在 Scala 3 中,像`[A] => List[A] => List[A]`这样的[polymorphic function types][types-polymorphic]可以抽象出除值参数外还接受 _类型参数_ 的函数。 + +- **Type lambdas**. 在 Scala 2 中需要用[编译器插件](https://github.com/typelevel/kind-projector)来表达的东西,现在在 Scala 3 中是第一类的功能:类型lambdas是类型级别的函数,可以作为(高等类型的)类型参数传递,而不需要辅助类型定义。 + +- **Match types**. Scala 3 提供了对[matching on types][types-match]的直接支持,而不是使用隐式解析对类型级别的计算进行编码。将类型级计算整合到类型检查器中,可以改进错误信息,并消除对复杂编码的需求。 + +### 重新设想的:面向对象的编程 + +Scala 一直处于函数式编程和面向对象编程的前沿 -- 而 Scala 3 在这两个方向上都推动了边界的发展! 上述类型系统的变化和上下文抽象的重新设计使得 _函数式编程_ 比以前更容易。同时,以下的新特性使结构良好的 _面向对象设计_ 成为可能,并支持最佳实践。 + +- **Pass it on**. Trait 更接近于 class,现在也可以接受[参数][oo-trait-parameters],使其作为模块化软件分解的工具更加强大。 + +- **Plan for extension**. 在面向对象的设计中,扩展那些不打算扩展的类是一个长期存在的问题。为了解决这个问题,[open classes][oo-open]要求库设计者 _明确地_ 将类标记为 open(开放的)。 + +- **Hide implementation details**. 实施行为的实用性traits有时不应该是推断类型的一部分。在 Scala 3 中,这些traits可以被标记为[transparent][oo-transparent],(在推断类型中)向用户隐藏继承性。 + +- **Composition over inheritance**. 这句话经常被引用,但实现起来却很繁琐。Scala 3 的[export clauses][oo-export]则不然:与imports对应,export clauses 允许用户为对象的选定成员定义别名。 + +- **No more NPEs**. Scala 3 比以往任何时候都更安全:[explicit null][oo-explicit-null]将`null`移出了类型层次结构,帮助你静态地捕捉错误;[safe initialization][oo-safe-init]的额外检查可以检测对未初始化对象的访问。 + +### Batteries Included: 元编程 +Scala 2 中的宏只是一个实验性的功能,而 Scala 3 则为元编程提供了强大的工具库。[宏教程]({% link _overviews/scala3-macros/tutorial/index.md %})中包含了关于不同设施的详细信息。特别是,Scala 3 为元编程提供了以下功能: + +作为基本的起点,[inline feature][meta-inline]允许在编译时减少数值和方法。这个简单的功能已经涵盖了许多使用情况,同时也为更高级的功能提供了入口。 + +- **Inline**. [inline feature][meta-inline]允许在编译时减少数值和方法。这个简单的功能已经涵盖了许多使用情况,同时也为更高级的功能提供了入口。 +- **Compile-time operations**. 包[`scala.compiletime`][meta-compiletime]中包含了额外的功能,可以用来实现内联方法。 +- **Quoted code blocks**. Scala 3为代码增加了[quasi-quotation][meta-quotes]的新功能,这为构建和分析代码提供了方便的高级接口。构建加一加一的代码就像`'{ 1 + 1 }`一样简单。 +- **Reflection API**. 对于更高级的用例,[quotes.reflect][meta-reflection]提供了更详细的控制来检查和生成程序树。 + + +如果你想进一步了解 Scala 3 中的元编程,我们邀请你参加我们的[教程][meta-tutorial]。 + +[enums]: {{ site.scala3ref }}/enums/enums.html +[enums-adts]: {{ site.scala3ref }}/enums/adts.html + +[types-intersection]: {{ site.scala3ref }}/new-types/intersection-types.html +[types-union]: {{ site.scala3ref }}/new-types/union-types.html +[types-dependent]: {{ site.scala3ref }}/new-types/dependent-function-types.html +[types-lambdas]: {{ site.scala3ref }}/new-types/type-lambdas.html +[types-polymorphic]: {{ site.scala3ref }}/new-types/polymorphic-function-types.html +[types-match]: {{ site.scala3ref }}/new-types/match-types.html +[types-opaque]: {{ site.scala3ref }}/other-new-features/opaques.html + +[type-inference]: {{ site.scala3ref }}/changed-features/type-inference.html +[overload-resolution]: {{ site.scala3ref }}/changed-features/overload-resolution.html +[reference]: {{ site.scala3ref }}/overview.html +[creator]: {{ site.scala3ref }}/other-new-features/creator-applications.html +[migration]: {% link _overviews/scala3-migration/compatibility-intro.md %} +[contribution]: {% link _overviews/scala3-contribution/contribution-intro.md %} + +[implicits]: {{ site.scala3ref }}/contextual.html +[contextual-using]: {{ site.scala3ref }}/contextual/using-clauses.html +[contextual-givens]: {{ site.scala3ref }}/contextual/givens.html +[contextual-extension]: {{ site.scala3ref }}/contextual/extension-methods.html +[contextual-conversions]: {{ site.scala3ref }}/contextual/conversions.html +[contextual-functions]: {{ site.scala3ref }}/contextual/context-functions.html + +[syntax-summary]: {{ site.scala3ref }}/syntax.html +[syntax-control]: {{ site.scala3ref }}/other-new-features/control-syntax.html +[syntax-indentation]: {{ site.scala3ref }}/other-new-features/indentation.html +[syntax-wildcard]: {{ site.scala3ref }}/changed-features/wildcards.html + +[meta-tutorial]: {% link _overviews/scala3-macros/tutorial/index.md %} +[meta-inline]: {% link _overviews/scala3-macros/tutorial/inline.md %} +[meta-compiletime]: {% link _overviews/scala3-macros/tutorial/compiletime.md %} +[meta-quotes]: {% link _overviews/scala3-macros/tutorial/quotes.md %} +[meta-reflection]: {% link _overviews/scala3-macros/tutorial/reflection.md %} + +[oo-explicit-null]: {{ site.scala3ref }}/other-new-features/explicit-nulls.html +[oo-safe-init]: {{ site.scala3ref }}/other-new-features/safe-initialization.html +[oo-trait-parameters]: {{ site.scala3ref }}/other-new-features/trait-parameters.html +[oo-open]: {{ site.scala3ref }}/other-new-features/open-classes.html +[oo-transparent]: {{ site.scala3ref }}/other-new-features/transparent-traits.html +[oo-export]: {{ site.scala3ref }}/other-new-features/export.html diff --git a/scala3/new-in-scala3.md b/scala3/new-in-scala3.md index af6d6111c1..5b30d76158 100644 --- a/scala3/new-in-scala3.md +++ b/scala3/new-in-scala3.md @@ -1,7 +1,7 @@ --- layout: singlepage-overview title: New in Scala 3 -languages: ["ja"] +languages: ["ja","zh-cn"] --- The exciting new version of Scala 3 brings many improvements and new features. Here we provide you with a quick overview of the most important From afcaefc6d26c42d36da3bbad2d1ef81244b01a48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=A6=E5=A2=83=E8=BF=B7=E7=A6=BB?= Date: Mon, 11 Apr 2022 20:25:45 +0800 Subject: [PATCH 1832/3075] fix --- _zh-cn/scala3/new-in-scala3.md | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/_zh-cn/scala3/new-in-scala3.md b/_zh-cn/scala3/new-in-scala3.md index 28b458c8d5..472f66331f 100644 --- a/_zh-cn/scala3/new-in-scala3.md +++ b/_zh-cn/scala3/new-in-scala3.md @@ -17,7 +17,7 @@ Scala 3 是对 Scala 语言的一次彻底改造。在其核心部分,类型 ### 新的和闪亮的:语法 -除了许多(小的)清理,Scala 3 的语法还提供了以下改进: +除了许多(小的)清理工作,Scala 3 的语法还提供了以下改进: - 用于控制结构的新“quiet”语法,如 `if`、`while` 和 `for` 。 ([new control syntax][syntax-control]) - `new` 关键字是可选的 (_aka_ [creator applications][creator]) @@ -34,9 +34,9 @@ Scala的一个基本核心概念是(在某种程度上仍然是)为用户提 - **Retroactively extending classes**. 在 Scala 2 中,扩展方法必须使用隐式转换或隐式类进行编码。相比之下,在 Scala 3 中,[extension methods][contextual-extension]现在直接内置于语言中,从而产生更好的错误消息和改进的类型推断。 -- **Viewing one type as another**. 隐式转换已经被重新[设计][contextual-conversions]为类型类转`Conversion`的实例。 +- **Viewing one type as another**. [隐式转换][contextual-conversions]已经被重新设计为类型类`Conversion`的实例。 -- **Higher-order contextual abstractions**. [context functions][contextual-functions]的 _全新_ 功能使上下文抽象成为一流的公民。它们是库作者的一个重要工具,允许表达简洁的特定领域语言。 +- **Higher-order contextual abstractions**. [context functions][contextual-functions]的 _全新_ 功能使上下文抽象成为一流的公民。它们是库开发人员的一个重要工具,允许表达简洁的特定领域语言。 - **Actionable feedback from the compiler**. 如果一个隐式参数不能被编译器解决,它现在提供了可能解决这个问题的[import suggestions](https://www.scala-lang.org/blog/2020/05/05/scala-3-import-suggestions.html)。 @@ -74,15 +74,13 @@ Scala 一直处于函数式编程和面向对象编程的前沿 -- 而 Scala 3 ### Batteries Included: 元编程 Scala 2 中的宏只是一个实验性的功能,而 Scala 3 则为元编程提供了强大的工具库。[宏教程]({% link _overviews/scala3-macros/tutorial/index.md %})中包含了关于不同设施的详细信息。特别是,Scala 3 为元编程提供了以下功能: -作为基本的起点,[inline feature][meta-inline]允许在编译时减少数值和方法。这个简单的功能已经涵盖了许多使用情况,同时也为更高级的功能提供了入口。 - - **Inline**. [inline feature][meta-inline]允许在编译时减少数值和方法。这个简单的功能已经涵盖了许多使用情况,同时也为更高级的功能提供了入口。 - **Compile-time operations**. 包[`scala.compiletime`][meta-compiletime]中包含了额外的功能,可以用来实现内联方法。 - **Quoted code blocks**. Scala 3为代码增加了[quasi-quotation][meta-quotes]的新功能,这为构建和分析代码提供了方便的高级接口。构建加一加一的代码就像`'{ 1 + 1 }`一样简单。 - **Reflection API**. 对于更高级的用例,[quotes.reflect][meta-reflection]提供了更详细的控制来检查和生成程序树。 -如果你想进一步了解 Scala 3 中的元编程,我们邀请你参加我们的[教程][meta-tutorial]。 +如果你想进一步了解 Scala 3 中的元编程,我们邀请你参加[教程][meta-tutorial]。 [enums]: {{ site.scala3ref }}/enums/enums.html [enums-adts]: {{ site.scala3ref }}/enums/adts.html From 9109395ffc43c7168daf02d0b328aca7c116ec39 Mon Sep 17 00:00:00 2001 From: Gord Currie <1119730+gordcurrie@users.noreply.github.com> Date: Mon, 11 Apr 2022 09:04:42 -0500 Subject: [PATCH 1833/3075] Update implicit casting example (#2370) --- _overviews/scala3-book/first-look-at-types.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/_overviews/scala3-book/first-look-at-types.md b/_overviews/scala3-book/first-look-at-types.md index c62e2cc9dd..85c3214ad9 100644 --- a/_overviews/scala3-book/first-look-at-types.md +++ b/_overviews/scala3-book/first-look-at-types.md @@ -238,20 +238,19 @@ Value types can be cast in the following way: For example: ```scala -val x: Long = 987654321 -val y: Float = x // 9.8765434E8 (note that some precision is lost in this case) +val b: Byte = 127 +val i: Int = b // 127 val face: Char = '☺' val number: Int = face // 9786 ``` -Casting is unidirectional. -This will not compile: +You can only cast to a type if there is no loss of information. Otherwise, you need to be explicit about the cast: -``` +```scala val x: Long = 987654321 -val y: Float = x // 9.8765434E8 -val z: Long = y // Does not conform +val y: Float = x.toFloat // 9.8765434E8 (note that `.toFloat` is required because the cast results in percision loss) +val z: Long = y // Error ``` You can also cast a reference type to a subtype. From 10c29916a9bfebaa979209d9421ff6d2a43d8e08 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Apr 2022 10:15:06 +0000 Subject: [PATCH 1834/3075] Bump nokogiri from 1.13.3 to 1.13.4 Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.13.3 to 1.13.4. - [Release notes](https://github.com/sparklemotion/nokogiri/releases) - [Changelog](https://github.com/sparklemotion/nokogiri/blob/v1.13.4/CHANGELOG.md) - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.13.3...v1.13.4) --- updated-dependencies: - dependency-name: nokogiri dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 5b52d7697a..3c6f6b8d12 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -55,7 +55,7 @@ GEM rb-inotify (~> 0.9, >= 0.9.10) mercenary (0.3.6) mini_portile2 (2.8.0) - nokogiri (1.13.3) + nokogiri (1.13.4) mini_portile2 (~> 2.8.0) racc (~> 1.4) nokogumbo (2.0.2) From b9926e655a75be592d5fae52ca894e0490901692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marks?= Date: Tue, 12 Apr 2022 15:46:45 +0200 Subject: [PATCH 1835/3075] Update Scala version to 3.1.2 --- _config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.yml b/_config.yml index 43f6dfd536..accb4b5df1 100644 --- a/_config.yml +++ b/_config.yml @@ -17,7 +17,7 @@ keywords: scala-version: 2.13.8 scala-212-version: 2.12.15 -scala-3-version: 3.1.1 +scala-3-version: 3.1.2 collections: contribute_resources: From 10abafb233f9b2877585e4316cf30ab308bd7449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Marks?= Date: Tue, 12 Apr 2022 15:50:34 +0200 Subject: [PATCH 1836/3075] Add entry for the documentation --- api/all.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/api/all.md b/api/all.md index ea55e544d9..33566543b6 100644 --- a/api/all.md +++ b/api/all.md @@ -6,8 +6,8 @@ includeTOC: true ## Latest releases -* Scala 3.1.1 - * [Library API](https://www.scala-lang.org/api/3.1.1/) +* Scala 3.1.2 + * [Library API](https://www.scala-lang.org/api/3.1.2/) * Scala 2.13.8 * [Library API](https://www.scala-lang.org/api/2.13.8/) * [Compiler API](https://www.scala-lang.org/api/2.13.8/scala-compiler/scala/) @@ -60,6 +60,8 @@ https://scala-ci.typesafe.com/artifactory/scala-integration/org/scala-lang/ ## Previous releases +* Scala 3.1.1 + * [Library API](https://www.scala-lang.org/api/3.1.1/) * Scala 3.1.0 * [Library API](https://www.scala-lang.org/api/3.1.0/) * Scala 3.0.2 From 496e82cc9e0515c68f7359425728da91d8953a62 Mon Sep 17 00:00:00 2001 From: Jochen Schneider Date: Fri, 15 Apr 2022 18:37:06 +0200 Subject: [PATCH 1837/3075] Example variable typo --- _overviews/collections-2.13/maps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/collections-2.13/maps.md b/_overviews/collections-2.13/maps.md index 3a27586614..8dff664b27 100644 --- a/_overviews/collections-2.13/maps.md +++ b/_overviews/collections-2.13/maps.md @@ -62,7 +62,7 @@ Mutable maps support in addition the operations summarized in the following tabl | WHAT IT IS | WHAT IT DOES | | ------ | ------ | | **Additions and Updates:**| | -| `ms(k) = v` |(Or, written out, `ms.update(x, v)`). Adds mapping from key `k` to value `v` to map ms as a side effect, overwriting any previous mapping of `k`.| +| `ms(k) = v` |(Or, written out, `ms.update(k, v)`). Adds mapping from key `k` to value `v` to map ms as a side effect, overwriting any previous mapping of `k`.| | `ms.addOne(k -> v)`
or `ms += (k -> v)` |Adds mapping from key `k` to value `v` to map `ms` as a side effect and returns `ms` itself.| | `ms addAll xvs`
or `ms ++= kvs` |Adds all mappings in `kvs` to `ms` as a side effect and returns `ms` itself.| | `ms.put(k, v)` |Adds mapping from key `k` to value `v` to `ms` and returns any value previously associated with `k` as an option.| From 86724d38cd620fff0568b1b6399e047f81de24ec Mon Sep 17 00:00:00 2001 From: Philippus Date: Sat, 16 Apr 2022 10:56:08 +0200 Subject: [PATCH 1838/3075] Update scalatest to 3.2.11 in scala book --- _overviews/scala-book/sbt-scalatest-bdd.md | 4 ++-- _overviews/scala-book/sbt-scalatest-tdd.md | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/_overviews/scala-book/sbt-scalatest-bdd.md b/_overviews/scala-book/sbt-scalatest-bdd.md index ee20a8490e..5117bbc0fc 100644 --- a/_overviews/scala-book/sbt-scalatest-bdd.md +++ b/_overviews/scala-book/sbt-scalatest-bdd.md @@ -70,7 +70,7 @@ class MathUtilsSpec extends FunSpec { As you can see, this is a very different-looking style than the TDD tests in the previous lesson. If you’ve never used a BDD style of testing before, a main idea is that the tests should be relatively easy to read for one of the “domain experts” who work with the programmers to create the application. A few notes about this code: -- It uses the `FunSpec` class where the TDD tests used `FunSuite` +- It uses the `AnyFunSpec` class where the TDD tests used `AnyFunSuite` - A set of tests begins with `describe` - Each test begins with `it`. The idea is that the test should read like, “It should do XYZ...,” where “it” is the `double` function - This example also shows how to mark a test as “pending” @@ -96,7 +96,7 @@ With those files in place you can again run `sbt test`. The important part of th [info] Suites: completed 2, aborted 0 [info] Tests: succeeded 4, failed 0, canceled 0, ignored 0, pending 1 [info] All tests passed. -[success] Total time: 4 s, completed Jan 6, 2018 4:58:23 PM +[success] Total time: 4 s ```` A few notes about that output: diff --git a/_overviews/scala-book/sbt-scalatest-tdd.md b/_overviews/scala-book/sbt-scalatest-tdd.md index 7214566a09..a0c61da35c 100644 --- a/_overviews/scala-book/sbt-scalatest-tdd.md +++ b/_overviews/scala-book/sbt-scalatest-tdd.md @@ -39,7 +39,7 @@ version := "1.0" scalaVersion := "{{site.scala-version}}" libraryDependencies += - "org.scalatest" %% "scalatest" % "3.0.8" % Test + "org.scalatest" %% "scalatest" % "3.2.11" % Test ``` @@ -47,7 +47,7 @@ The first three lines of this file are essentially the same as the first example ```scala libraryDependencies += - "org.scalatest" %% "scalatest" % "3.0.8" % Test + "org.scalatest" %% "scalatest" % "3.2.11" % Test ``` >The ScalaTest documentation has always been good, and you can always find the up to date information on what those lines should look like on the [Installing ScalaTest](http://www.scalatest.org/install) page. @@ -85,8 +85,8 @@ There isn’t much that can go wrong with that source code, but it provides a si [warn] consider launching sbt without any commands, or explicitly passing 'shell' ... ... -[info] Compiling 1 Scala source to /Users/al/Projects/Scala/HelloScalaTest/target/scala-2.12/classes... -[info] Running simpletest.Hello +[info] compiling 1 Scala source to /Users/al/Projects/Scala/HelloScalaTest/target/scala-2.13/classes... +[info] running simpletest.Hello Hello Alvin Alexander [success] Total time: 4 s ```` @@ -108,9 +108,9 @@ Next, create a file named *HelloTests.scala* in that directory with the followin ```scala package simpletest -import org.scalatest.FunSuite +import org.scalatest.funsuite.AnyFunSuite -class HelloTests extends FunSuite { +class HelloTests extends AnyFunSuite { // test 1 test("the name is set correctly in constructor") { @@ -130,7 +130,7 @@ class HelloTests extends FunSuite { This file demonstrates the ScalaTest `FunSuite` approach. A few important points: -- Your class should extend `FunSuite` +- Your class should extend `AnyFunSuite` - You create tests as shown, by giving each `test` a unique name - At the end of each test you should call `assert` to test that a condition has been satisfied @@ -140,7 +140,7 @@ Now you can run these tests with the `sbt test` command. Skipping the first few ```` > sbt test -[info] Set current project to HelloScalaTest (in build file:/Users/al/Projects/Scala/HelloScalaTest/) +[info] set current project to HelloScalaTest (in build file:/Users/al/Projects/Scala/HelloScalaTest/) [info] HelloTests: [info] - the name is set correctly in constructor [info] - a Person's name can be changed From 9ac6061ceacad3e7a8906abe49e6a8f2504ac2f4 Mon Sep 17 00:00:00 2001 From: Philippus Date: Sat, 16 Apr 2022 10:56:35 +0200 Subject: [PATCH 1839/3075] Update scalatest to 3.2.11 in IntelliJ example --- .../testing-scala-in-intellij-with-scalatest.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/_getting-started/intellij-track/testing-scala-in-intellij-with-scalatest.md b/_getting-started/intellij-track/testing-scala-in-intellij-with-scalatest.md index 77d0b3341a..fb34580984 100644 --- a/_getting-started/intellij-track/testing-scala-in-intellij-with-scalatest.md +++ b/_getting-started/intellij-track/testing-scala-in-intellij-with-scalatest.md @@ -20,15 +20,15 @@ This assumes you know [how to build a project in IntelliJ](building-a-scala-proj 1. Add the ScalaTest dependency: 1. Add the ScalaTest dependency to your `build.sbt` file: ``` - libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.8" % Test + libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.11" % Test ``` 1. If you get a notification "build.sbt was changed", select **auto-import**. 1. These two actions will cause `sbt` to download the ScalaTest library. - 1. Wait for the `sbt` sync to finish; otherwise, `FunSuite` and `test()` will be + 1. Wait for the `sbt` sync to finish; otherwise, `AnyFunSuite` and `test()` will be unrecognized. 1. On the project pane on the left, expand `src` => `main`. 1. Right-click on `scala` and select **New** => **Scala class**. -1. Call it `CubeCalculator`, change the **Kind** to `object`, and click **OK**. +1. Call it `CubeCalculator`, change the **Kind** to `object`, and hit enter or double click on `object`. 1. Replace the code with the following: ``` object CubeCalculator extends App { @@ -41,12 +41,12 @@ This assumes you know [how to build a project in IntelliJ](building-a-scala-proj ## Creating a test 1. On the project pane on the left, expand `src` => `test`. 1. Right-click on `scala` and select **New** => **Scala class**. -1. Name the class `CubeCalculatorTest` and click **OK**. +1. Name the class `CubeCalculatorTest` and hit enter or double click on `class`. 1. Replace the code with the following: ``` - import org.scalatest.FunSuite + import org.scalatest.funsuite.AnyFunSuite - class CubeCalculatorTest extends FunSuite { + class CubeCalculatorTest extends AnyFunSuite { test("CubeCalculator.cube") { assert(CubeCalculator.cube(3) === 27) } @@ -60,9 +60,9 @@ This assumes you know [how to build a project in IntelliJ](building-a-scala-proj Let's go over this line by line: * `class CubeCalculatorTest` means we are testing the object `CubeCalculator` -* `extends FunSuite` lets us use functionality of ScalaTest's FunSuite class +* `extends AnyFunSuite` lets us use functionality of ScalaTest's AnyFunSuite class such as the `test` function -* `test` is function that comes from the FunSuite library that collects +* `test` is a function that comes from the FunSuite library that collects results from assertions within the function body. * `"CubeCalculator.cube"` is a name for the test. You can call it anything but one convention is "ClassName.methodName". From 533d497ffc5c11e24f3efb5dbf67b387a4872083 Mon Sep 17 00:00:00 2001 From: Philippus Date: Sat, 16 Apr 2022 14:18:31 +0200 Subject: [PATCH 1840/3075] Drop references to Discourse comments --- _ja/tour/abstract-type-members.md | 4 ---- _ja/tour/annotations.md | 5 ----- _ja/tour/automatic-closures.md | 3 --- _ja/tour/basics.md | 5 ----- _ja/tour/by-name-parameters.md | 5 ----- _ja/tour/case-classes.md | 5 ----- _ja/tour/classes.md | 5 ----- _ja/tour/compound-types.md | 5 ----- _ja/tour/default-parameter-values.md | 5 ----- _ja/tour/extractor-objects.md | 5 ----- _ja/tour/for-comprehensions.md | 5 ----- _ja/tour/generic-classes.md | 5 ----- _ja/tour/higher-order-functions.md | 5 ----- _ja/tour/implicit-conversions.md | 5 ----- _ja/tour/implicit-parameters.md | 5 ----- _ja/tour/inner-classes.md | 5 ----- _ja/tour/lower-type-bounds.md | 5 ----- _ja/tour/mixin-class-composition.md | 5 ----- _ja/tour/multiple-parameter-lists.md | 5 ----- _ja/tour/named-arguments.md | 5 ----- _ja/tour/nested-functions.md | 5 ----- _ja/tour/operators.md | 5 ----- _ja/tour/package-objects.md | 4 ---- _ja/tour/packages-and-imports.md | 4 ---- _ja/tour/pattern-matching.md | 6 ------ _ja/tour/polymorphic-methods.md | 6 ------ _ja/tour/regular-expression-patterns.md | 6 ------ _ja/tour/self-types.md | 5 ----- _ja/tour/singleton-objects.md | 5 ----- _ja/tour/tour-of-scala.md | 6 ------ _ja/tour/traits.md | 5 ----- _ja/tour/tuples.md | 5 ----- _ja/tour/type-inference.md | 4 ---- _ja/tour/unified-types.md | 5 ----- _ja/tour/upper-type-bounds.md | 4 ---- _ja/tour/variances.md | 5 ----- _ja/tutorials/scala-for-java-programmers.md | 3 --- _overviews/scala-book/abstract-classes.md | 1 - _overviews/scala-book/anonymous-functions.md | 1 - _overviews/scala-book/arraybuffer-examples.md | 1 - _overviews/scala-book/built-in-types.md | 1 - _overviews/scala-book/case-classes.md | 1 - _overviews/scala-book/case-objects.md | 1 - _overviews/scala-book/classes-aux-constructors.md | 1 - _overviews/scala-book/classes.md | 1 - _overviews/scala-book/collections-101.md | 1 - _overviews/scala-book/collections-maps.md | 1 - _overviews/scala-book/collections-methods.md | 1 - _overviews/scala-book/command-line-io.md | 1 - _overviews/scala-book/companion-objects.md | 1 - _overviews/scala-book/concurrency-signpost.md | 1 - _overviews/scala-book/constructors-default-values.md | 1 - _overviews/scala-book/control-structures.md | 1 - _overviews/scala-book/enumerations-pizza-class.md | 1 - _overviews/scala-book/for-expressions.md | 1 - _overviews/scala-book/for-loops.md | 1 - _overviews/scala-book/functional-error-handling.md | 1 - _overviews/scala-book/functional-programming.md | 1 - _overviews/scala-book/futures.md | 1 - _overviews/scala-book/hello-world-1.md | 1 - _overviews/scala-book/hello-world-2.md | 1 - _overviews/scala-book/if-then-else-construct.md | 1 - _overviews/scala-book/list-class.md | 1 - _overviews/scala-book/map-class.md | 1 - _overviews/scala-book/match-expressions.md | 1 - _overviews/scala-book/methods-first-look.md | 1 - _overviews/scala-book/misc.md | 1 - _overviews/scala-book/no-null-values.md | 1 - _overviews/scala-book/oop-pizza-example.md | 1 - _overviews/scala-book/passing-functions-around.md | 1 - _overviews/scala-book/preliminaries.md | 1 - _overviews/scala-book/prelude-taste-of-scala.md | 1 - _overviews/scala-book/pure-functions.md | 1 - _overviews/scala-book/sbt-scalatest-bdd.md | 1 - _overviews/scala-book/sbt-scalatest-intro.md | 1 - _overviews/scala-book/sbt-scalatest-tdd.md | 1 - _overviews/scala-book/scala-build-tool-sbt.md | 1 - _overviews/scala-book/scala-features.md | 1 - _overviews/scala-book/scala-repl.md | 1 - _overviews/scala-book/set-class.md | 1 - _overviews/scala-book/traits-abstract-mixins.md | 1 - _overviews/scala-book/traits-interfaces.md | 1 - _overviews/scala-book/traits-intro.md | 1 - _overviews/scala-book/try-catch-finally.md | 1 - _overviews/scala-book/tuples.md | 1 - _overviews/scala-book/two-notes-about-strings.md | 1 - _overviews/scala-book/two-types-variables.md | 1 - _overviews/scala-book/type-is-optional.md | 1 - _overviews/scala-book/vector-class.md | 1 - _overviews/scala-book/where-next.md | 1 - _overviews/scaladoc/contribute.md | 5 ----- _overviews/scaladoc/generate.md | 5 ----- _ru/overviews/collections-2.13/arrays.md | 5 ----- .../concrete-immutable-collection-classes.md | 6 ------ .../collections-2.13/concrete-mutable-collection-classes.md | 6 ------ .../conversions-between-java-and-scala-collections.md | 6 ------ .../collections-2.13/creating-collections-from-scratch.md | 6 ------ _ru/overviews/collections-2.13/equality.md | 6 ------ _ru/overviews/collections-2.13/introduction.md | 6 ------ _ru/overviews/collections-2.13/iterators.md | 6 ------ _ru/overviews/collections-2.13/maps.md | 6 ------ _ru/overviews/collections-2.13/overview.md | 6 ------ .../collections-2.13/performance-characteristics.md | 6 ------ _ru/overviews/collections-2.13/seqs.md | 6 ------ _ru/overviews/collections-2.13/sets.md | 6 ------ _ru/overviews/collections-2.13/strings.md | 6 ------ _ru/overviews/collections-2.13/trait-iterable.md | 6 ------ _ru/overviews/collections-2.13/views.md | 6 ------ _ru/overviews/collections/introduction.md | 5 ----- _ru/overviews/parallel-collections/architecture.md | 3 --- .../parallel-collections/concrete-parallel-collections.md | 4 ---- _ru/overviews/parallel-collections/configuration.md | 4 ---- _ru/overviews/parallel-collections/conversions.md | 4 ---- _ru/overviews/parallel-collections/ctries.md | 4 ---- .../parallel-collections/custom-parallel-collections.md | 4 ---- _ru/overviews/parallel-collections/overview.md | 4 ---- _ru/overviews/parallel-collections/performance.md | 4 ---- _ru/tour/abstract-type-members.md | 4 ---- _ru/tour/annotations.md | 5 ----- _ru/tour/automatic-closures.md | 2 -- _ru/tour/basics.md | 5 ----- _ru/tour/by-name-parameters.md | 5 ----- _ru/tour/case-classes.md | 5 ----- _ru/tour/classes.md | 5 ----- _ru/tour/compound-types.md | 5 ----- _ru/tour/default-parameter-values.md | 5 ----- _ru/tour/extractor-objects.md | 5 ----- _ru/tour/for-comprehensions.md | 5 ----- _ru/tour/generic-classes.md | 5 ----- _ru/tour/higher-order-functions.md | 5 ----- _ru/tour/implicit-conversions.md | 5 ----- _ru/tour/implicit-parameters.md | 5 ----- _ru/tour/inner-classes.md | 5 ----- _ru/tour/lower-type-bounds.md | 5 ----- _ru/tour/mixin-class-composition.md | 5 ----- _ru/tour/multiple-parameter-lists.md | 5 ----- _ru/tour/named-arguments.md | 5 ----- _ru/tour/nested-functions.md | 5 ----- _ru/tour/operators.md | 5 ----- _ru/tour/package-objects.md | 4 ---- _ru/tour/packages-and-imports.md | 4 ---- _ru/tour/pattern-matching.md | 5 ----- _ru/tour/polymorphic-methods.md | 5 ----- _ru/tour/regular-expression-patterns.md | 5 ----- _ru/tour/self-types.md | 5 ----- _ru/tour/singleton-objects.md | 4 ---- _ru/tour/tour-of-scala.md | 4 ---- _ru/tour/traits.md | 5 ----- _ru/tour/tuples.md | 5 ----- _ru/tour/type-inference.md | 4 ---- _ru/tour/unified-types.md | 5 ----- _ru/tour/upper-type-bounds.md | 4 ---- _ru/tour/variances.md | 5 ----- 153 files changed, 544 deletions(-) diff --git a/_ja/tour/abstract-type-members.md b/_ja/tour/abstract-type-members.md index 2f480833bf..af08eb5c2b 100644 --- a/_ja/tour/abstract-type-members.md +++ b/_ja/tour/abstract-type-members.md @@ -2,16 +2,12 @@ layout: tour title: 抽象型メンバー language: ja - -discourse: true - partof: scala-tour num: 23 next-page: compound-types previous-page: inner-classes topics: abstract type members prerequisite-knowledge: variance, upper-type-bound - --- トレイトや抽象クラスのような抽象型は抽象型メンバーを持つことができます。 diff --git a/_ja/tour/annotations.md b/_ja/tour/annotations.md index d0fad2e82a..90545140fc 100644 --- a/_ja/tour/annotations.md +++ b/_ja/tour/annotations.md @@ -2,15 +2,10 @@ layout: tour title: アノテーション language: ja - -discourse: true - partof: scala-tour - num: 32 next-page: packages-and-imports previous-page: by-name-parameters - --- アノテーションはメタ情報と定義を関連づけます。例えば、メソッドの前のアノテーション`@deprecated`はメソッドが使われたらコンパイラに警告を出力させます。 diff --git a/_ja/tour/automatic-closures.md b/_ja/tour/automatic-closures.md index 3b38e98178..0ba4911aa2 100644 --- a/_ja/tour/automatic-closures.md +++ b/_ja/tour/automatic-closures.md @@ -2,9 +2,6 @@ layout: tour title: 型依存クロージャの自動構築 language: ja - -discourse: true - partof: scala-tour --- diff --git a/_ja/tour/basics.md b/_ja/tour/basics.md index b2b06317bb..09c7033f3a 100644 --- a/_ja/tour/basics.md +++ b/_ja/tour/basics.md @@ -2,15 +2,10 @@ layout: tour title: 基本 language: ja - -discourse: true - partof: scala-tour - num: 2 next-page: unified-types previous-page: tour-of-scala - --- このページでは、Scalaの基本を取り扱います。 diff --git a/_ja/tour/by-name-parameters.md b/_ja/tour/by-name-parameters.md index c3494f5634..b88f6dd617 100644 --- a/_ja/tour/by-name-parameters.md +++ b/_ja/tour/by-name-parameters.md @@ -2,15 +2,10 @@ layout: tour title: 名前渡しパラメータ language: ja - -discourse: true - partof: scala-tour - num: 31 next-page: annotations previous-page: operators - --- *名前渡しのパラメータ*は使用された時に評価されます。それらは*値渡しパラメータ*とは対照的です。名前渡しのパラメータを作るには、単純に`=>`を型の前につけます。 diff --git a/_ja/tour/case-classes.md b/_ja/tour/case-classes.md index 65cce59c9b..2015b843c1 100644 --- a/_ja/tour/case-classes.md +++ b/_ja/tour/case-classes.md @@ -2,16 +2,11 @@ layout: tour title: ケースクラス language: ja - -discourse: true - partof: scala-tour - num: 11 next-page: pattern-matching previous-page: multiple-parameter-lists prerequisite-knowledge: classes, basics, mutability - --- ケースクラスはこれから論じるいくつかの差異はあるものの普通のクラスと似ています。 diff --git a/_ja/tour/classes.md b/_ja/tour/classes.md index e594b4ea37..74bd6c6997 100644 --- a/_ja/tour/classes.md +++ b/_ja/tour/classes.md @@ -2,17 +2,12 @@ layout: tour title: クラス language: ja - -discourse: true - partof: scala-tour - num: 4 next-page: traits previous-page: unified-types topics: classes prerequisite-knowledge: no-return-keyword, type-declaration-syntax, string-interpolation, procedures - --- Scalaにおけるクラスはオブジェクトを作るための設計図です。 diff --git a/_ja/tour/compound-types.md b/_ja/tour/compound-types.md index 60be4af3c3..2137ecc432 100644 --- a/_ja/tour/compound-types.md +++ b/_ja/tour/compound-types.md @@ -2,15 +2,10 @@ layout: tour title: 複合型 language: ja - -discourse: true - partof: scala-tour - num: 24 next-page: self-types previous-page: abstract-type-members - --- ときどき、あるオブジェクトの型が、複数の他の型のサブタイプであると表現する必要が生じます。 Scalaでは、これは*複合型*を用いて表現できます。複合型とはオブジェクトの型同士を重ねることです。 diff --git a/_ja/tour/default-parameter-values.md b/_ja/tour/default-parameter-values.md index 1e03cebe50..499f543566 100644 --- a/_ja/tour/default-parameter-values.md +++ b/_ja/tour/default-parameter-values.md @@ -2,16 +2,11 @@ layout: tour title: デフォルト引数 language: ja - -discourse: true - partof: scala-tour - num: 33 next-page: named-arguments previous-page: annotations prerequisite-knowledge: named-arguments, function syntax - --- Scalaはパラメータのデフォルト値を与えることができ、呼び出す側はこれらのパラメータを省略できます。 diff --git a/_ja/tour/extractor-objects.md b/_ja/tour/extractor-objects.md index ba4603a3fa..6dac1d2209 100644 --- a/_ja/tour/extractor-objects.md +++ b/_ja/tour/extractor-objects.md @@ -2,15 +2,10 @@ layout: tour title: 抽出子オブジェクト language: ja - -discourse: true - partof: scala-tour - num: 16 next-page: for-comprehensions previous-page: regular-expression-patterns - --- 抽出子オブジェクトは`unapply`メソッドを持つオブジェクトです。 diff --git a/_ja/tour/for-comprehensions.md b/_ja/tour/for-comprehensions.md index c673135b2b..1600904350 100644 --- a/_ja/tour/for-comprehensions.md +++ b/_ja/tour/for-comprehensions.md @@ -2,15 +2,10 @@ layout: tour title: for内包表記 language: ja - -discourse: true - partof: scala-tour - num: 17 next-page: generic-classes previous-page: extractor-objects - --- Scalaは*シーケンス内包表記*を表現するための軽量な記法を提供します。 diff --git a/_ja/tour/generic-classes.md b/_ja/tour/generic-classes.md index 2de82cc5ce..ad944b8b39 100644 --- a/_ja/tour/generic-classes.md +++ b/_ja/tour/generic-classes.md @@ -2,16 +2,11 @@ layout: tour title: ジェネリッククラス language: ja - -discourse: true - partof: scala-tour - num: 18 next-page: variances previous-page: for-comprehensions assumed-knowledge: classes unified-types - --- ジェネリッククラスはパラメータとして型を1つ受け取るクラスです。それらはコレクションクラスで特に役立ちます。 diff --git a/_ja/tour/higher-order-functions.md b/_ja/tour/higher-order-functions.md index 1740d1ba3d..773ca7170b 100644 --- a/_ja/tour/higher-order-functions.md +++ b/_ja/tour/higher-order-functions.md @@ -2,15 +2,10 @@ layout: tour title: 高階関数 language: ja - -discourse: true - partof: scala-tour - num: 8 next-page: nested-functions previous-page: mixin-class-composition - --- 高階関数は他の関数をパラメーターとして受け取る、もしくは結果として関数を返します。 diff --git a/_ja/tour/implicit-conversions.md b/_ja/tour/implicit-conversions.md index 8ee5a23069..d4de2375f3 100644 --- a/_ja/tour/implicit-conversions.md +++ b/_ja/tour/implicit-conversions.md @@ -2,15 +2,10 @@ layout: tour title: 暗黙の変換 language: ja - -discourse: true - partof: scala-tour - num: 27 next-page: polymorphic-methods previous-page: implicit-parameters - --- 型`S`から型`T`への暗黙の変換は`S => T`という型のimplicit値や、その型に一致するimplicitメソッドで定義されます。 diff --git a/_ja/tour/implicit-parameters.md b/_ja/tour/implicit-parameters.md index 30ff6028df..db43cd76fc 100644 --- a/_ja/tour/implicit-parameters.md +++ b/_ja/tour/implicit-parameters.md @@ -2,15 +2,10 @@ layout: tour title: 暗黙のパラメータ language: ja - -discourse: true - partof: scala-tour - num: 26 next-page: implicit-conversions previous-page: self-types - --- メソッドは _暗黙の_ パラメータのリストを持つことができ、パラメータリストの先頭には _implicit_ キーワードで印をつけます。 diff --git a/_ja/tour/inner-classes.md b/_ja/tour/inner-classes.md index 5d38b1f1f6..2bc8ecf450 100644 --- a/_ja/tour/inner-classes.md +++ b/_ja/tour/inner-classes.md @@ -2,15 +2,10 @@ layout: tour title: 内部クラス language: ja - -discourse: true - partof: scala-tour - num: 22 next-page: abstract-type-members previous-page: lower-type-bounds - --- Scalaではクラスが他のクラスをメンバーとして保持することが可能です。 diff --git a/_ja/tour/lower-type-bounds.md b/_ja/tour/lower-type-bounds.md index 62a15447d3..e72a3773f8 100644 --- a/_ja/tour/lower-type-bounds.md +++ b/_ja/tour/lower-type-bounds.md @@ -2,16 +2,11 @@ layout: tour title: 下限型境界 language: ja - -discourse: true - partof: scala-tour - num: 21 next-page: inner-classes previous-page: upper-type-bounds prerequisite-knowledge: upper-type-bounds, generics, variance - --- [上限型境界](upper-type-bounds.html) は型を別の型のサブタイプに制限しますが、*下限型境界*は型が別の型のスーパータイプであることを宣言します。表現`B >: A`はパラメータ`B`または抽象型`B`が型`A`のスーパータイプであることを表します。ほとんどのケースで`A`はそのクラスの型パラメータであり、`B`はメソッドの型パラメータになります。 diff --git a/_ja/tour/mixin-class-composition.md b/_ja/tour/mixin-class-composition.md index 8b4e26067e..f95ab54cb9 100644 --- a/_ja/tour/mixin-class-composition.md +++ b/_ja/tour/mixin-class-composition.md @@ -2,16 +2,11 @@ layout: tour title: ミックスインを用いたクラス合成 language: ja - -discourse: true - partof: scala-tour - num: 7 next-page: higher-order-functions previous-page: tuples prerequisite-knowledge: inheritance, traits, abstract-classes, unified-types - --- ミックスインはクラスを構成するのに使われるトレイトです。 diff --git a/_ja/tour/multiple-parameter-lists.md b/_ja/tour/multiple-parameter-lists.md index ff267531b8..c9b70ec998 100644 --- a/_ja/tour/multiple-parameter-lists.md +++ b/_ja/tour/multiple-parameter-lists.md @@ -2,15 +2,10 @@ layout: tour title: 複数パラメータリスト(カリー化) language: ja - -discourse: true - partof: scala-tour - num: 10 next-page: case-classes previous-page: nested-functions - --- メソッドは複数のパラメータリストを持てます。 diff --git a/_ja/tour/named-arguments.md b/_ja/tour/named-arguments.md index 8ce70335a9..88bc231fda 100644 --- a/_ja/tour/named-arguments.md +++ b/_ja/tour/named-arguments.md @@ -2,16 +2,11 @@ layout: tour title: 名前付き引数 language: ja - -discourse: true - partof: scala-tour - num: 34 next-page: packages-and-imports previous-page: default-parameter-values prerequisite-knowledge: function-syntax - --- メソッドを呼ぶ時、以下のように引数にパラメータ名でラベル付が可能です。 diff --git a/_ja/tour/nested-functions.md b/_ja/tour/nested-functions.md index 9701e421cc..9fa581bc3e 100644 --- a/_ja/tour/nested-functions.md +++ b/_ja/tour/nested-functions.md @@ -2,15 +2,10 @@ layout: tour title: ネストしたメソッド language: ja - -discourse: true - partof: scala-tour - num: 9 next-page: multiple-parameter-lists previous-page: higher-order-functions - --- Scalaではメソッドの定義をネストする(_訳注:入れ子にする_)ことができます。 diff --git a/_ja/tour/operators.md b/_ja/tour/operators.md index 7df5800aa1..398790b4e0 100644 --- a/_ja/tour/operators.md +++ b/_ja/tour/operators.md @@ -2,16 +2,11 @@ layout: tour title: 演算子 language: ja - -discourse: true - partof: scala-tour - num: 30 next-page: by-name-parameters previous-page: type-inference prerequisite-knowledge: case-classes - --- Scalaでは演算子はメソッドです。パラメータを1つだけ持つメソッドであれば*中置演算子*として使えます。例えば、`+`はドット記法で呼び出せます。 diff --git a/_ja/tour/package-objects.md b/_ja/tour/package-objects.md index 755935d3ef..f2ed9b1d89 100644 --- a/_ja/tour/package-objects.md +++ b/_ja/tour/package-objects.md @@ -2,11 +2,7 @@ layout: tour title: パッケージオブジェクト language: ja - -discourse: true - partof: scala-tour - num: 36 previous-page: packages-and-imports --- diff --git a/_ja/tour/packages-and-imports.md b/_ja/tour/packages-and-imports.md index 8e44239b05..4e94731644 100644 --- a/_ja/tour/packages-and-imports.md +++ b/_ja/tour/packages-and-imports.md @@ -2,11 +2,7 @@ layout: tour title: パッケージとインポート language: ja - -discourse: true - partof: scala-tour - num: 35 previous-page: named-arguments next-page: package-objects diff --git a/_ja/tour/pattern-matching.md b/_ja/tour/pattern-matching.md index 9e1f5d9692..23c997ca91 100644 --- a/_ja/tour/pattern-matching.md +++ b/_ja/tour/pattern-matching.md @@ -2,17 +2,11 @@ layout: tour title: パターンマッチング language: ja - -discourse: true - partof: scala-tour - num: 12 - next-page: singleton-objects previous-page: case-classes prerequisite-knowledge: case-classes, string-interpolation, subtyping - --- パターンマッチングは値をパターンに照合するための仕組みです。 diff --git a/_ja/tour/polymorphic-methods.md b/_ja/tour/polymorphic-methods.md index 6143ef2612..4bab5f63bd 100644 --- a/_ja/tour/polymorphic-methods.md +++ b/_ja/tour/polymorphic-methods.md @@ -2,17 +2,11 @@ layout: tour title: ポリモーフィックメソッド language: ja - -discourse: true - partof: scala-tour - num: 28 - next-page: type-inference previous-page: implicit-conversions prerequisite-knowledge: unified-types - --- Scalaのメソッドは値と同様に型によってパラメータ化することができます。構文はジェネリッククラスの構文と似ています。 diff --git a/_ja/tour/regular-expression-patterns.md b/_ja/tour/regular-expression-patterns.md index 05882529c0..79cf565c9f 100644 --- a/_ja/tour/regular-expression-patterns.md +++ b/_ja/tour/regular-expression-patterns.md @@ -2,16 +2,10 @@ layout: tour title: 正規表現パターン language: ja - -discourse: true - partof: scala-tour - num: 15 - next-page: extractor-objects previous-page: singleton-objects - --- 正規表現はデータの中からパターン(またはその欠如)を探すために使うことができる文字列です。 どんな文字列も`.r`メソッドを使うことで、正規表現に変換できます。 diff --git a/_ja/tour/self-types.md b/_ja/tour/self-types.md index cb585dc09e..7ffa6745ec 100644 --- a/_ja/tour/self-types.md +++ b/_ja/tour/self-types.md @@ -2,17 +2,12 @@ layout: tour title: 自分型 language: ja - -discourse: true - partof: scala-tour - num: 25 next-page: implicit-parameters previous-page: compound-types topics: self-types prerequisite-knowledge: nested-classes, mixin-class-composition - --- 自分型は、直接継承していなくてもトレイトが他のトレイトにミックスインされていることを宣言する方法です。 これにより依存先のメンバーをimportなしで利用できます。 diff --git a/_ja/tour/singleton-objects.md b/_ja/tour/singleton-objects.md index 69ce1aeede..0414291909 100644 --- a/_ja/tour/singleton-objects.md +++ b/_ja/tour/singleton-objects.md @@ -2,13 +2,8 @@ layout: tour title: シングルトンオブジェクト language: ja - -discourse: true - partof: scala-tour - num: 13 - next-page: regular-expression-patterns previous-page: pattern-matching prerequisite-knowledge: classes, methods, private-methods, packages, option diff --git a/_ja/tour/tour-of-scala.md b/_ja/tour/tour-of-scala.md index ff2d026686..9e5d2b9860 100644 --- a/_ja/tour/tour-of-scala.md +++ b/_ja/tour/tour-of-scala.md @@ -2,15 +2,9 @@ layout: tour title: 前書き language: ja - -discourse: true - partof: scala-tour - num: 1 - next-page: basics - --- ## ようこそツアーへ diff --git a/_ja/tour/traits.md b/_ja/tour/traits.md index 81b7dc7046..1738b0fc0d 100644 --- a/_ja/tour/traits.md +++ b/_ja/tour/traits.md @@ -2,17 +2,12 @@ layout: tour title: トレイト language: ja - -discourse: true - partof: scala-tour - num: 5 next-page: tuples previous-page: classes topics: traits prerequisite-knowledge: expressions, classes, generics, objects, companion-objects - --- トレイトはクラス間でインターフェースとフィールドを共有するために使います。それらはJava 8のインターフェースと似ています。 diff --git a/_ja/tour/tuples.md b/_ja/tour/tuples.md index 7729138914..e3c2f1e0f7 100644 --- a/_ja/tour/tuples.md +++ b/_ja/tour/tuples.md @@ -2,16 +2,11 @@ layout: tour title: タプル language: ja - -discourse: true - partof: scala-tour - num: 6 next-page: mixin-class-composition previous-page: traits topics: tuples - --- Scalaではタプルは決まった数の要素を含む値であり、各要素はそれぞれの型を持ちます。 diff --git a/_ja/tour/type-inference.md b/_ja/tour/type-inference.md index 2db0e440b9..5973da20a2 100644 --- a/_ja/tour/type-inference.md +++ b/_ja/tour/type-inference.md @@ -2,11 +2,7 @@ layout: tour title: 型推論 language: ja - -discourse: true - partof: scala-tour - num: 29 next-page: operators previous-page: polymorphic-methods diff --git a/_ja/tour/unified-types.md b/_ja/tour/unified-types.md index 8f9710b62a..a12895c677 100644 --- a/_ja/tour/unified-types.md +++ b/_ja/tour/unified-types.md @@ -2,16 +2,11 @@ layout: tour title: 統合された型 language: ja - -discourse: true - partof: scala-tour - num: 3 next-page: classes previous-page: basics prerequisite-knowledge: classes, basics - --- Scalaでは数値や関数を含め、全ての値は型を持ちます。 以下の図は型階層の一部を説明しています。 diff --git a/_ja/tour/upper-type-bounds.md b/_ja/tour/upper-type-bounds.md index 7d8ac4df9a..8dfe6ca8ac 100644 --- a/_ja/tour/upper-type-bounds.md +++ b/_ja/tour/upper-type-bounds.md @@ -2,15 +2,11 @@ layout: tour title: 上限型境界 language: ja - -discourse: true - partof: scala-tour categories: tour num: 20 next-page: lower-type-bounds previous-page: variances - --- Scalaでは [型パラメータ](generic-classes.html)と[抽象型メンバー](abstract-type-members.html) は型境界による制約をかけることができます。 diff --git a/_ja/tour/variances.md b/_ja/tour/variances.md index c7eb10304e..314f8c2e48 100644 --- a/_ja/tour/variances.md +++ b/_ja/tour/variances.md @@ -2,15 +2,10 @@ layout: tour title: 変位指定 language: ja - -discourse: true - partof: scala-tour - num: 19 next-page: upper-type-bounds previous-page: generic-classes - --- 変位指定は複合型の間の継承関係とそれらの型パラメータ間の継承関係の相関です。 diff --git a/_ja/tutorials/scala-for-java-programmers.md b/_ja/tutorials/scala-for-java-programmers.md index b49113ff72..a2076100b1 100644 --- a/_ja/tutorials/scala-for-java-programmers.md +++ b/_ja/tutorials/scala-for-java-programmers.md @@ -1,10 +1,7 @@ --- layout: singlepage-overview title: JavaプログラマーのためのScalaチュートリアル - partof: scala-for-java-programmers - -discourse: false language: ja --- diff --git a/_overviews/scala-book/abstract-classes.md b/_overviews/scala-book/abstract-classes.md index a5ec3b96fa..ed8dc3b147 100644 --- a/_overviews/scala-book/abstract-classes.md +++ b/_overviews/scala-book/abstract-classes.md @@ -5,7 +5,6 @@ title: Abstract Classes description: This page shows how to use abstract classes, including when and why you should use abstract classes. partof: scala_book overview-name: Scala Book -discourse: true num: 27 outof: 54 previous-page: traits-abstract-mixins diff --git a/_overviews/scala-book/anonymous-functions.md b/_overviews/scala-book/anonymous-functions.md index bbd7bc8d8d..de9c9ebd14 100644 --- a/_overviews/scala-book/anonymous-functions.md +++ b/_overviews/scala-book/anonymous-functions.md @@ -5,7 +5,6 @@ title: Anonymous Functions description: This page shows how to use anonymous functions in Scala, including examples with the List class 'map' and 'filter' functions. partof: scala_book overview-name: Scala Book -discourse: true num: 34 outof: 54 previous-page: set-class diff --git a/_overviews/scala-book/arraybuffer-examples.md b/_overviews/scala-book/arraybuffer-examples.md index 8d4dd8ef53..1f0206e58f 100644 --- a/_overviews/scala-book/arraybuffer-examples.md +++ b/_overviews/scala-book/arraybuffer-examples.md @@ -5,7 +5,6 @@ title: The ArrayBuffer Class description: This page provides examples of how to use the Scala ArrayBuffer class, including adding and removing elements. partof: scala_book overview-name: Scala Book -discourse: true num: 29 outof: 54 previous-page: collections-101 diff --git a/_overviews/scala-book/built-in-types.md b/_overviews/scala-book/built-in-types.md index 209b1b8f0b..1567d13970 100644 --- a/_overviews/scala-book/built-in-types.md +++ b/_overviews/scala-book/built-in-types.md @@ -5,7 +5,6 @@ title: A Few Built-In Types description: A brief introduction to Scala's built-in types. partof: scala_book overview-name: Scala Book -discourse: true num: 10 outof: 54 previous-page: type-is-optional diff --git a/_overviews/scala-book/case-classes.md b/_overviews/scala-book/case-classes.md index 8722d4c5ae..33db4a9a7f 100644 --- a/_overviews/scala-book/case-classes.md +++ b/_overviews/scala-book/case-classes.md @@ -5,7 +5,6 @@ title: Case Classes description: This lesson provides an introduction to 'case classes' in Scala. partof: scala_book overview-name: Scala Book -discourse: true num: 49 outof: 54 previous-page: companion-objects diff --git a/_overviews/scala-book/case-objects.md b/_overviews/scala-book/case-objects.md index 1b7426f12a..ca6a5f155a 100644 --- a/_overviews/scala-book/case-objects.md +++ b/_overviews/scala-book/case-objects.md @@ -5,7 +5,6 @@ title: Case Objects description: This lesson introduces Scala 'case objects', which are used to create singletons with a few additional features. partof: scala_book overview-name: Scala Book -discourse: true num: 50 outof: 54 previous-page: case-classes diff --git a/_overviews/scala-book/classes-aux-constructors.md b/_overviews/scala-book/classes-aux-constructors.md index a66a4b4d80..d3af412a53 100644 --- a/_overviews/scala-book/classes-aux-constructors.md +++ b/_overviews/scala-book/classes-aux-constructors.md @@ -5,7 +5,6 @@ title: Auxiliary Class Constructors description: This page shows how to write auxiliary Scala class constructors, including several examples of the syntax. partof: scala_book overview-name: Scala Book -discourse: true num: 20 outof: 54 previous-page: classes diff --git a/_overviews/scala-book/classes.md b/_overviews/scala-book/classes.md index bc4fe65b66..c4861bc7c2 100644 --- a/_overviews/scala-book/classes.md +++ b/_overviews/scala-book/classes.md @@ -5,7 +5,6 @@ title: Scala Classes description: This page shows examples of how to create Scala classes, including the basic Scala class constructor. partof: scala_book overview-name: Scala Book -discourse: true num: 19 outof: 54 previous-page: try-catch-finally diff --git a/_overviews/scala-book/collections-101.md b/_overviews/scala-book/collections-101.md index 6df136b528..b98a72d116 100644 --- a/_overviews/scala-book/collections-101.md +++ b/_overviews/scala-book/collections-101.md @@ -5,7 +5,6 @@ title: Scala Collections description: This page provides an introduction to the Scala collections classes, including Vector, List, ArrayBuffer, Map, Set, and more. partof: scala_book overview-name: Scala Book -discourse: true num: 28 outof: 54 previous-page: abstract-classes diff --git a/_overviews/scala-book/collections-maps.md b/_overviews/scala-book/collections-maps.md index 95e890bbc3..84a9f065c4 100644 --- a/_overviews/scala-book/collections-maps.md +++ b/_overviews/scala-book/collections-maps.md @@ -5,7 +5,6 @@ title: Common Map Methods description: This page shows examples of the most common methods that are available on Scala Maps. partof: scala_book overview-name: Scala Book -discourse: true num: 36 outof: 54 previous-page: collections-methods diff --git a/_overviews/scala-book/collections-methods.md b/_overviews/scala-book/collections-methods.md index 7bd8d9a15a..e888179940 100644 --- a/_overviews/scala-book/collections-methods.md +++ b/_overviews/scala-book/collections-methods.md @@ -5,7 +5,6 @@ title: Common Sequence Methods description: This page shows examples of the most common methods that are available on the Scala sequences (collections classes). partof: scala_book overview-name: Scala Book -discourse: true num: 35 outof: 54 previous-page: anonymous-functions diff --git a/_overviews/scala-book/command-line-io.md b/_overviews/scala-book/command-line-io.md index ffb35f698e..14bf2901af 100644 --- a/_overviews/scala-book/command-line-io.md +++ b/_overviews/scala-book/command-line-io.md @@ -5,7 +5,6 @@ title: Command-Line I/O description: An introduction to command-line I/O in Scala. partof: scala_book overview-name: Scala Book -discourse: true num: 12 outof: 54 previous-page: two-notes-about-strings diff --git a/_overviews/scala-book/companion-objects.md b/_overviews/scala-book/companion-objects.md index 6babb21eb9..f024a8a2d5 100644 --- a/_overviews/scala-book/companion-objects.md +++ b/_overviews/scala-book/companion-objects.md @@ -5,7 +5,6 @@ title: Companion Objects description: This lesson provides an introduction to 'companion objects' in Scala, including writing 'apply' and 'unapply' methods. partof: scala_book overview-name: Scala Book -discourse: true num: 48 outof: 54 previous-page: no-null-values diff --git a/_overviews/scala-book/concurrency-signpost.md b/_overviews/scala-book/concurrency-signpost.md index 1629700299..d3435c4ede 100644 --- a/_overviews/scala-book/concurrency-signpost.md +++ b/_overviews/scala-book/concurrency-signpost.md @@ -5,7 +5,6 @@ title: Concurrency description: An introduction to concurrency in Scala. partof: scala_book overview-name: Scala Book -discourse: true num: 52 outof: 54 previous-page: functional-error-handling diff --git a/_overviews/scala-book/constructors-default-values.md b/_overviews/scala-book/constructors-default-values.md index aa4429305e..b54da93584 100644 --- a/_overviews/scala-book/constructors-default-values.md +++ b/_overviews/scala-book/constructors-default-values.md @@ -5,7 +5,6 @@ title: Supplying Default Values for Constructor Parameters description: This page shows how to provide default values for Scala constructor parameters, with several examples. partof: scala_book overview-name: Scala Book -discourse: true num: 21 outof: 54 previous-page: classes-aux-constructors diff --git a/_overviews/scala-book/control-structures.md b/_overviews/scala-book/control-structures.md index 813a05face..9d21b18eb3 100644 --- a/_overviews/scala-book/control-structures.md +++ b/_overviews/scala-book/control-structures.md @@ -5,7 +5,6 @@ title: Control Structures description: This page provides an introduction to Scala's control structures, including if/then/else, for loops, try/catch/finally, etc. partof: scala_book overview-name: Scala Book -discourse: true num: 13 outof: 54 previous-page: command-line-io diff --git a/_overviews/scala-book/enumerations-pizza-class.md b/_overviews/scala-book/enumerations-pizza-class.md index 31625129f0..d4052378bb 100644 --- a/_overviews/scala-book/enumerations-pizza-class.md +++ b/_overviews/scala-book/enumerations-pizza-class.md @@ -5,7 +5,6 @@ title: Enumerations (and a Complete Pizza Class) description: This page introduces Scala enumerations, and further shows how to create a complete OOP 'Pizza' class that uses those enumerations. partof: scala_book overview-name: Scala Book -discourse: true num: 23 outof: 54 previous-page: methods-first-look diff --git a/_overviews/scala-book/for-expressions.md b/_overviews/scala-book/for-expressions.md index 7977777872..4cd666ef42 100644 --- a/_overviews/scala-book/for-expressions.md +++ b/_overviews/scala-book/for-expressions.md @@ -5,7 +5,6 @@ title: for Expressions description: This page shows how to use Scala 'for' expressions (also known as 'for-expressions'), including examples of how to use it with the 'yield' keyword. partof: scala_book overview-name: Scala Book -discourse: true num: 16 outof: 54 previous-page: for-loops diff --git a/_overviews/scala-book/for-loops.md b/_overviews/scala-book/for-loops.md index 5eef6cc279..ef382270f2 100644 --- a/_overviews/scala-book/for-loops.md +++ b/_overviews/scala-book/for-loops.md @@ -5,7 +5,6 @@ title: for Loops description: This page provides an introduction to the Scala 'for' loop, including how to iterate over Scala collections. partof: scala_book overview-name: Scala Book -discourse: true num: 15 outof: 54 previous-page: if-then-else-construct diff --git a/_overviews/scala-book/functional-error-handling.md b/_overviews/scala-book/functional-error-handling.md index 00a448ccc0..8e779a2bc2 100644 --- a/_overviews/scala-book/functional-error-handling.md +++ b/_overviews/scala-book/functional-error-handling.md @@ -5,7 +5,6 @@ title: Functional Error Handling in Scala description: This lesson takes a look at error handling with functional programming in Scala. partof: scala_book overview-name: Scala Book -discourse: true num: 51 outof: 54 previous-page: case-objects diff --git a/_overviews/scala-book/functional-programming.md b/_overviews/scala-book/functional-programming.md index aa0581cf87..dee9cc4533 100644 --- a/_overviews/scala-book/functional-programming.md +++ b/_overviews/scala-book/functional-programming.md @@ -5,7 +5,6 @@ title: Functional Programming description: This lesson begins a second on 'An introduction to functional programming in Scala'. partof: scala_book overview-name: Scala Book -discourse: true num: 44 outof: 54 previous-page: sbt-scalatest-bdd diff --git a/_overviews/scala-book/futures.md b/_overviews/scala-book/futures.md index 9324b0ddf9..e585ff2819 100644 --- a/_overviews/scala-book/futures.md +++ b/_overviews/scala-book/futures.md @@ -5,7 +5,6 @@ title: Scala Futures description: This page provides an introduction to Futures in Scala, including Future callback methods. partof: scala_book overview-name: Scala Book -discourse: true num: 53 outof: 54 previous-page: concurrency-signpost diff --git a/_overviews/scala-book/hello-world-1.md b/_overviews/scala-book/hello-world-1.md index c9793a2376..28aa21f19b 100644 --- a/_overviews/scala-book/hello-world-1.md +++ b/_overviews/scala-book/hello-world-1.md @@ -5,7 +5,6 @@ title: Hello, World description: This page shares a Scala 'Hello, world' example. partof: scala_book overview-name: Scala Book -discourse: true num: 5 outof: 54 previous-page: scala-features diff --git a/_overviews/scala-book/hello-world-2.md b/_overviews/scala-book/hello-world-2.md index d07b7da00f..76d1bf053c 100644 --- a/_overviews/scala-book/hello-world-2.md +++ b/_overviews/scala-book/hello-world-2.md @@ -5,7 +5,6 @@ title: Hello, World - Version 2 description: This is a second Scala 'Hello, World' example. partof: scala_book overview-name: Scala Book -discourse: true num: 6 outof: 54 previous-page: hello-world-1 diff --git a/_overviews/scala-book/if-then-else-construct.md b/_overviews/scala-book/if-then-else-construct.md index 6fd09ef879..bd720f758a 100644 --- a/_overviews/scala-book/if-then-else-construct.md +++ b/_overviews/scala-book/if-then-else-construct.md @@ -5,7 +5,6 @@ title: The if/then/else Construct description: This page demonstrates Scala's if/then/else construct, including several examples you can try in the REPL. partof: scala_book overview-name: Scala Book -discourse: true num: 14 outof: 54 previous-page: control-structures diff --git a/_overviews/scala-book/list-class.md b/_overviews/scala-book/list-class.md index 1a606afc98..0e4e324e89 100644 --- a/_overviews/scala-book/list-class.md +++ b/_overviews/scala-book/list-class.md @@ -5,7 +5,6 @@ title: The List Class description: This page provides examples of the Scala List class, including how to add and remove elements from a List. partof: scala_book overview-name: Scala Book -discourse: true num: 30 outof: 54 previous-page: arraybuffer-examples diff --git a/_overviews/scala-book/map-class.md b/_overviews/scala-book/map-class.md index 4a7d48db98..34f0824fae 100644 --- a/_overviews/scala-book/map-class.md +++ b/_overviews/scala-book/map-class.md @@ -5,7 +5,6 @@ title: The Map Class description: This page provides examples of the Scala 'Map' class, including how to add and remove elements from a Map, and iterate over Map elements. partof: scala_book overview-name: Scala Book -discourse: true num: 32 outof: 54 previous-page: vector-class diff --git a/_overviews/scala-book/match-expressions.md b/_overviews/scala-book/match-expressions.md index 4b54dfb35c..60cc0d92ae 100644 --- a/_overviews/scala-book/match-expressions.md +++ b/_overviews/scala-book/match-expressions.md @@ -5,7 +5,6 @@ title: match Expressions description: This page shows examples of the Scala 'match' expression, including how to write match/case expressions. partof: scala_book overview-name: Scala Book -discourse: true num: 17 outof: 54 previous-page: for-expressions diff --git a/_overviews/scala-book/methods-first-look.md b/_overviews/scala-book/methods-first-look.md index 7e10bdfd77..348c66f56f 100644 --- a/_overviews/scala-book/methods-first-look.md +++ b/_overviews/scala-book/methods-first-look.md @@ -5,7 +5,6 @@ title: A First Look at Scala Methods description: This page provides a first look at how to write Scala methods, including how to test them in the REPL. partof: scala_book overview-name: Scala Book -discourse: true num: 22 outof: 54 previous-page: constructors-default-values diff --git a/_overviews/scala-book/misc.md b/_overviews/scala-book/misc.md index 61c19bd1b2..07f511305c 100644 --- a/_overviews/scala-book/misc.md +++ b/_overviews/scala-book/misc.md @@ -5,7 +5,6 @@ title: A Few Miscellaneous Items description: A few miscellaneous items about Scala partof: scala_book overview-name: Scala Book -discourse: true num: 37 outof: 54 previous-page: collections-maps diff --git a/_overviews/scala-book/no-null-values.md b/_overviews/scala-book/no-null-values.md index 757fc62670..194348c246 100644 --- a/_overviews/scala-book/no-null-values.md +++ b/_overviews/scala-book/no-null-values.md @@ -5,7 +5,6 @@ title: No Null Values description: This lesson demonstrates the Scala Option, Some, and None classes, including how to use them instead of null values. partof: scala_book overview-name: Scala Book -discourse: true num: 47 outof: 54 previous-page: passing-functions-around diff --git a/_overviews/scala-book/oop-pizza-example.md b/_overviews/scala-book/oop-pizza-example.md index 7d50686e71..c70df45e3f 100644 --- a/_overviews/scala-book/oop-pizza-example.md +++ b/_overviews/scala-book/oop-pizza-example.md @@ -5,7 +5,6 @@ title: An OOP Example description: This lesson shares an example of some OOP-style classes for a pizza restaurant order entry system, including Pizza, Topping, and Order classes. partof: scala_book overview-name: Scala Book -discourse: true num: 39 outof: 54 previous-page: tuples diff --git a/_overviews/scala-book/passing-functions-around.md b/_overviews/scala-book/passing-functions-around.md index 2700ea06c7..80c6cd2f2b 100644 --- a/_overviews/scala-book/passing-functions-around.md +++ b/_overviews/scala-book/passing-functions-around.md @@ -5,7 +5,6 @@ title: Passing Functions Around description: Like a good functional programming language, Scala lets you use functions just like other variables, including passing them into other functions. partof: scala_book overview-name: Scala Book -discourse: true num: 46 outof: 54 previous-page: pure-functions diff --git a/_overviews/scala-book/preliminaries.md b/_overviews/scala-book/preliminaries.md index e8057e37d9..ac3af5ea33 100644 --- a/_overviews/scala-book/preliminaries.md +++ b/_overviews/scala-book/preliminaries.md @@ -5,7 +5,6 @@ title: Preliminaries description: A few things to know about getting started with Scala. partof: scala_book overview-name: Scala Book -discourse: true num: 3 outof: 54 previous-page: prelude-taste-of-scala diff --git a/_overviews/scala-book/prelude-taste-of-scala.md b/_overviews/scala-book/prelude-taste-of-scala.md index 1317561825..aba0111219 100644 --- a/_overviews/scala-book/prelude-taste-of-scala.md +++ b/_overviews/scala-book/prelude-taste-of-scala.md @@ -5,7 +5,6 @@ title: Prelude꞉ A Taste of Scala description: This page shares a Taste Of Scala example, quickly covering Scala's main features. partof: scala_book overview-name: Scala Book -discourse: true num: 2 outof: 54 previous-page: introduction diff --git a/_overviews/scala-book/pure-functions.md b/_overviews/scala-book/pure-functions.md index 97c6ef6fb9..5bbb4f50c2 100644 --- a/_overviews/scala-book/pure-functions.md +++ b/_overviews/scala-book/pure-functions.md @@ -5,7 +5,6 @@ title: Pure Functions description: This lesson provides an introduction to writing pure functions in Scala. partof: scala_book overview-name: Scala Book -discourse: true num: 45 outof: 54 previous-page: functional-programming diff --git a/_overviews/scala-book/sbt-scalatest-bdd.md b/_overviews/scala-book/sbt-scalatest-bdd.md index ee20a8490e..6bb134abdb 100644 --- a/_overviews/scala-book/sbt-scalatest-bdd.md +++ b/_overviews/scala-book/sbt-scalatest-bdd.md @@ -5,7 +5,6 @@ title: Writing BDD Style Tests with ScalaTest and sbt description: This lesson shows how to write ScalaTest unit tests with sbt in a behavior-driven development (TDD) style. partof: scala_book overview-name: Scala Book -discourse: true num: 43 outof: 54 previous-page: sbt-scalatest-tdd diff --git a/_overviews/scala-book/sbt-scalatest-intro.md b/_overviews/scala-book/sbt-scalatest-intro.md index bf40ba8c6c..e7f8d20bed 100644 --- a/_overviews/scala-book/sbt-scalatest-intro.md +++ b/_overviews/scala-book/sbt-scalatest-intro.md @@ -5,7 +5,6 @@ title: sbt and ScalaTest description: In this lesson we'll start to introduce sbt and ScalaTest, two tools commonly used on Scala projects. partof: scala_book overview-name: Scala Book -discourse: true num: 40 outof: 54 previous-page: oop-pizza-example diff --git a/_overviews/scala-book/sbt-scalatest-tdd.md b/_overviews/scala-book/sbt-scalatest-tdd.md index 7214566a09..724d9c1728 100644 --- a/_overviews/scala-book/sbt-scalatest-tdd.md +++ b/_overviews/scala-book/sbt-scalatest-tdd.md @@ -5,7 +5,6 @@ title: Using ScalaTest with sbt description: This lesson shows how to write ScalaTest unit tests with sbt in a test-driven development (TDD) style. partof: scala_book overview-name: Scala Book -discourse: true num: 42 outof: 54 previous-page: scala-build-tool-sbt diff --git a/_overviews/scala-book/scala-build-tool-sbt.md b/_overviews/scala-book/scala-build-tool-sbt.md index 8986433976..aefb28ecea 100644 --- a/_overviews/scala-book/scala-build-tool-sbt.md +++ b/_overviews/scala-book/scala-build-tool-sbt.md @@ -5,7 +5,6 @@ title: The most used scala build tool (sbt) description: This page provides an introduction to the Scala Build Tool, sbt, including a simple 'Hello, world' project. partof: scala_book overview-name: Scala Book -discourse: true num: 41 outof: 54 previous-page: sbt-scalatest-intro diff --git a/_overviews/scala-book/scala-features.md b/_overviews/scala-book/scala-features.md index eee55bd089..c7d7387d4a 100644 --- a/_overviews/scala-book/scala-features.md +++ b/_overviews/scala-book/scala-features.md @@ -5,7 +5,6 @@ title: Scala Features description: TODO partof: scala_book overview-name: Scala Book -discourse: true num: 4 outof: 54 previous-page: preliminaries diff --git a/_overviews/scala-book/scala-repl.md b/_overviews/scala-book/scala-repl.md index c1ced1f219..062ca12b7f 100644 --- a/_overviews/scala-book/scala-repl.md +++ b/_overviews/scala-book/scala-repl.md @@ -5,7 +5,6 @@ title: The Scala REPL description: This page shares an introduction to the Scala REPL. partof: scala_book overview-name: Scala Book -discourse: true num: 7 outof: 54 previous-page: hello-world-2 diff --git a/_overviews/scala-book/set-class.md b/_overviews/scala-book/set-class.md index 55fefb31d0..dc69cb2ae4 100644 --- a/_overviews/scala-book/set-class.md +++ b/_overviews/scala-book/set-class.md @@ -5,7 +5,6 @@ title: The Set Class description: This page provides examples of the Scala 'Set' class, including how to add and remove elements from a Set, and iterate over Set elements. partof: scala_book overview-name: Scala Book -discourse: true num: 33 outof: 54 previous-page: map-class diff --git a/_overviews/scala-book/traits-abstract-mixins.md b/_overviews/scala-book/traits-abstract-mixins.md index eeecb67aee..db3ab56d63 100644 --- a/_overviews/scala-book/traits-abstract-mixins.md +++ b/_overviews/scala-book/traits-abstract-mixins.md @@ -5,7 +5,6 @@ title: Using Scala Traits Like Abstract Classes description: This page shows how to use Scala traits just like abstract classes in Java, with examples of concrete and abstract methods. partof: scala_book overview-name: Scala Book -discourse: true num: 26 outof: 54 previous-page: traits-interfaces diff --git a/_overviews/scala-book/traits-interfaces.md b/_overviews/scala-book/traits-interfaces.md index a10ed18a61..f422f158bc 100644 --- a/_overviews/scala-book/traits-interfaces.md +++ b/_overviews/scala-book/traits-interfaces.md @@ -5,7 +5,6 @@ title: Using Scala Traits as Interfaces description: This page shows how to use Scala traits just like Java interfaces, including several examples. partof: scala_book overview-name: Scala Book -discourse: true num: 25 outof: 54 previous-page: traits-intro diff --git a/_overviews/scala-book/traits-intro.md b/_overviews/scala-book/traits-intro.md index a6d1db0f26..75656b4a64 100644 --- a/_overviews/scala-book/traits-intro.md +++ b/_overviews/scala-book/traits-intro.md @@ -5,7 +5,6 @@ title: Scala Traits and Abstract Classes description: An introduction to Scala traits and abstract classes. partof: scala_book overview-name: Scala Book -discourse: true num: 24 outof: 54 previous-page: enumerations-pizza-class diff --git a/_overviews/scala-book/try-catch-finally.md b/_overviews/scala-book/try-catch-finally.md index 5dee7890a4..607bf3fc0b 100644 --- a/_overviews/scala-book/try-catch-finally.md +++ b/_overviews/scala-book/try-catch-finally.md @@ -5,7 +5,6 @@ title: try/catch/finally Expressions description: This page shows how to use Scala's try/catch/finally construct, including several complete examples. partof: scala_book overview-name: Scala Book -discourse: true num: 18 outof: 54 previous-page: match-expressions diff --git a/_overviews/scala-book/tuples.md b/_overviews/scala-book/tuples.md index c2eb8e4225..568037274b 100644 --- a/_overviews/scala-book/tuples.md +++ b/_overviews/scala-book/tuples.md @@ -5,7 +5,6 @@ title: Tuples description: This page is an introduction to the Scala 'tuple' data type, showing examples of how to use tuples in your Scala code. partof: scala_book overview-name: Scala Book -discourse: true num: 38 outof: 54 previous-page: misc diff --git a/_overviews/scala-book/two-notes-about-strings.md b/_overviews/scala-book/two-notes-about-strings.md index fdcbd7a29a..dea6f3e643 100644 --- a/_overviews/scala-book/two-notes-about-strings.md +++ b/_overviews/scala-book/two-notes-about-strings.md @@ -5,7 +5,6 @@ title: Two Notes About Strings description: This page shares two important notes about strings in Scala. partof: scala_book overview-name: Scala Book -discourse: true num: 11 outof: 54 previous-page: built-in-types diff --git a/_overviews/scala-book/two-types-variables.md b/_overviews/scala-book/two-types-variables.md index 678c89dc3d..f369c66a87 100644 --- a/_overviews/scala-book/two-types-variables.md +++ b/_overviews/scala-book/two-types-variables.md @@ -5,7 +5,6 @@ title: Two Types of Variables description: Scala has two types of variables, val and var. partof: scala_book overview-name: Scala Book -discourse: true num: 8 outof: 54 previous-page: scala-repl diff --git a/_overviews/scala-book/type-is-optional.md b/_overviews/scala-book/type-is-optional.md index 3b21654433..0d8b0a1c93 100644 --- a/_overviews/scala-book/type-is-optional.md +++ b/_overviews/scala-book/type-is-optional.md @@ -5,7 +5,6 @@ title: The Type is Optional description: A note about explicit and implicit data type declarations in Scala. partof: scala_book overview-name: Scala Book -discourse: true num: 9 outof: 54 previous-page: two-types-variables diff --git a/_overviews/scala-book/vector-class.md b/_overviews/scala-book/vector-class.md index 15981e7904..1c17c9183c 100644 --- a/_overviews/scala-book/vector-class.md +++ b/_overviews/scala-book/vector-class.md @@ -5,7 +5,6 @@ title: The Vector Class description: This page provides examples of the Scala 'Vector' class, including how to add and remove elements from a Vector. partof: scala_book overview-name: Scala Book -discourse: true num: 31 outof: 54 previous-page: list-class diff --git a/_overviews/scala-book/where-next.md b/_overviews/scala-book/where-next.md index 4b045d7182..6bce221a97 100644 --- a/_overviews/scala-book/where-next.md +++ b/_overviews/scala-book/where-next.md @@ -5,7 +5,6 @@ title: Where To Go Next description: Where to go next after reading the Scala Book partof: scala_book overview-name: Scala Book -discourse: true num: 54 outof: 54 previous-page: futures diff --git a/_overviews/scaladoc/contribute.md b/_overviews/scaladoc/contribute.md index dc0af2ce57..0d8999574a 100644 --- a/_overviews/scaladoc/contribute.md +++ b/_overviews/scaladoc/contribute.md @@ -1,14 +1,9 @@ --- layout: multipage-overview title: Contributing to Scaladoc - -discourse: true - partof: scaladoc overview-name: Scaladoc - num: 5 - permalink: /overviews/scaladoc/:title.html --- diff --git a/_overviews/scaladoc/generate.md b/_overviews/scaladoc/generate.md index 98c0942ffe..0fbd38d533 100644 --- a/_overviews/scaladoc/generate.md +++ b/_overviews/scaladoc/generate.md @@ -1,14 +1,9 @@ --- layout: multipage-overview title: Generating Scaladoc - -discourse: true - partof: scaladoc overview-name: Scaladoc - num: 4 - permalink: /overviews/scaladoc/:title.html --- diff --git a/_ru/overviews/collections-2.13/arrays.md b/_ru/overviews/collections-2.13/arrays.md index 7e71da1027..dba3fb4e08 100644 --- a/_ru/overviews/collections-2.13/arrays.md +++ b/_ru/overviews/collections-2.13/arrays.md @@ -1,17 +1,12 @@ --- layout: multipage-overview title: Массивы - -discourse: true - partof: collections-213 overview-name: Collections - num: 10 previous-page: concrete-mutable-collection-classes next-page: strings language: ru - --- [Массивы](https://www.scala-lang.org/api/{{ site.scala-version }}/scala/Array.html) особый вид коллекций в Scala. diff --git a/_ru/overviews/collections-2.13/concrete-immutable-collection-classes.md b/_ru/overviews/collections-2.13/concrete-immutable-collection-classes.md index 6da8bcc3e1..0c6a672ae0 100644 --- a/_ru/overviews/collections-2.13/concrete-immutable-collection-classes.md +++ b/_ru/overviews/collections-2.13/concrete-immutable-collection-classes.md @@ -1,18 +1,12 @@ --- layout: multipage-overview title: Реализации Неизменяемых Коллекций - -discourse: true - partof: collections-213 overview-name: Collections - previous-page: maps next-page: concrete-mutable-collection-classes - num: 8 language: ru - --- Scala предлагает множество конечных реализаций неизменяемых коллекций. Они отличаются реализуемыми трейтами (мапы (map), множества(set), последовательности(seq)), они могут быть бесконечными, и различаются производительностью операций. Вот некоторые из наиболее распространенных неизменяемых типов коллекций, используемых в Scala. diff --git a/_ru/overviews/collections-2.13/concrete-mutable-collection-classes.md b/_ru/overviews/collections-2.13/concrete-mutable-collection-classes.md index 7152037ce9..a65910b05a 100644 --- a/_ru/overviews/collections-2.13/concrete-mutable-collection-classes.md +++ b/_ru/overviews/collections-2.13/concrete-mutable-collection-classes.md @@ -1,18 +1,12 @@ --- layout: multipage-overview title: Реализации Изменяемых Коллекций - -discourse: true - partof: collections-213 overview-name: Collections - num: 9 previous-page: concrete-immutable-collection-classes next-page: arrays - language: ru - --- Вы уже успели увидеть наиболее часто используемые неизменяемые типы коллекции, которые есть в стандартной библиотеке Scala. Настало время посмотреть на изменяемые (mutable) типы коллекции. diff --git a/_ru/overviews/collections-2.13/conversions-between-java-and-scala-collections.md b/_ru/overviews/collections-2.13/conversions-between-java-and-scala-collections.md index 2471e0121f..0320c0c59d 100644 --- a/_ru/overviews/collections-2.13/conversions-between-java-and-scala-collections.md +++ b/_ru/overviews/collections-2.13/conversions-between-java-and-scala-collections.md @@ -1,17 +1,11 @@ --- layout: multipage-overview title: Преобразования между Java и Scala коллекциями - -discourse: true - partof: collections-213 overview-name: Collections - num: 17 previous-page: creating-collections-from-scratch - language: ru - --- Как и в Scala, в Java есть богатая библиотека коллекций. Между ними много общего. Например, обе библиотеки предоставляют итераторы, итерируемые сущности, множества, мапы и списки. Но есть и серьезные различия. В частности, библиотека Scala фокусируют больше внимания на неизменяемых коллекциях, предоставляя больше возможностей для преобразования исходной коллекции в новую. diff --git a/_ru/overviews/collections-2.13/creating-collections-from-scratch.md b/_ru/overviews/collections-2.13/creating-collections-from-scratch.md index 1eacea990f..25c9cb21cf 100644 --- a/_ru/overviews/collections-2.13/creating-collections-from-scratch.md +++ b/_ru/overviews/collections-2.13/creating-collections-from-scratch.md @@ -1,18 +1,12 @@ --- layout: multipage-overview title: Создание коллекций с нуля - -discourse: true - partof: collections-213 overview-name: Collections - num: 16 previous-page: iterators next-page: conversions-between-java-and-scala-collections - language: ru - --- У вас есть синтаксис `List(1, 2, 3)` для создания списка из трех целых чисел и `Map('A' -> 1, 'C' -> 2)` для создания мапы с двумя элементами. На самом деле, это универсальная функциональность коллекций Scala. Можно получить любую коллекцию написав ее название и указав следом список элементов в круглых скобках. В результате получится новая коллекция с заданными элементами. Вот еще несколько примеров: diff --git a/_ru/overviews/collections-2.13/equality.md b/_ru/overviews/collections-2.13/equality.md index 5908d1ca2b..179ae0bd71 100644 --- a/_ru/overviews/collections-2.13/equality.md +++ b/_ru/overviews/collections-2.13/equality.md @@ -1,18 +1,12 @@ --- layout: multipage-overview title: Равенство - -discourse: true - partof: collections-213 overview-name: Collections - num: 13 previous-page: performance-characteristics next-page: views - language: ru - --- Коллекций придерживаются единого подхода к определению равенства и получению хэшей. Идея состоит, во-первых, в том, чтобы разделить коллекции на группы: множества, мапы и последовательности. Коллекции в разных группах всегда различаются. Например, `Set(1,2,3)` неравнозначен списку `List(1,2,3)`, хотя они содержат одни и те же элементы. С другой стороны, в рамках одной и той же группы коллекции равны тогда и только тогда, когда они имеют одинаковые элементы (для последовательностей: одни и те же элементы в одном порядке). Например `List(1, 2, 3) == Vector(1, 2, 3)`, и `HashSet(1, 2) == TreeSet(2, 1)`. diff --git a/_ru/overviews/collections-2.13/introduction.md b/_ru/overviews/collections-2.13/introduction.md index c965ef979e..e97c142eb8 100644 --- a/_ru/overviews/collections-2.13/introduction.md +++ b/_ru/overviews/collections-2.13/introduction.md @@ -1,17 +1,11 @@ --- layout: multipage-overview title: Введение - -discourse: true - partof: collections-213 overview-name: Collections - num: 1 next-page: overview - language: ru - --- **Martin Odersky и Lex Spoon** diff --git a/_ru/overviews/collections-2.13/iterators.md b/_ru/overviews/collections-2.13/iterators.md index ee7c02c50d..a74e0bc860 100644 --- a/_ru/overviews/collections-2.13/iterators.md +++ b/_ru/overviews/collections-2.13/iterators.md @@ -1,18 +1,12 @@ --- layout: multipage-overview title: Итераторы - -discourse: true - partof: collections-213 overview-name: Collections - num: 15 previous-page: views next-page: creating-collections-from-scratch - language: ru - --- Итератор (Iterator) - это не коллекция, а скорее способ поочередного доступа к элементам коллекции. Есть две основные операции у итератора - это `next` и `hasNext`. Вызов метода `it.next()` на итераторе `it` вернет следующий элемент и изменит его состояние. Повторный вызов `next` на том же итераторе выведит следующий элемент идущий после ранее возвращённого. Если больше нет элементов для возврата, вызов команды `next` кинет исключение `NoSuchElementException`. Вы можете узнать, есть ли еще элементы для возврата с помощью метода `hasNext` у [Итератора](https://www.scala-lang.org/api/{{ site.scala-version }}/scala/collection/Iterator.html). diff --git a/_ru/overviews/collections-2.13/maps.md b/_ru/overviews/collections-2.13/maps.md index 18cfc11245..a3d93834fd 100644 --- a/_ru/overviews/collections-2.13/maps.md +++ b/_ru/overviews/collections-2.13/maps.md @@ -1,18 +1,12 @@ --- layout: multipage-overview title: Мапы - -discourse: true - partof: collections-213 overview-name: Collections - num: 7 previous-page: sets next-page: concrete-immutable-collection-classes - language: ru - --- [Map](https://www.scala-lang.org/api/current/scala/collection/Map.html) это [Iterable](https://www.scala-lang.org/api/current/scala/collection/Iterable.html) состоящее из пар ключ значение (также называемых _связкой_ или _ассоциативным массивом_). diff --git a/_ru/overviews/collections-2.13/overview.md b/_ru/overviews/collections-2.13/overview.md index b0fe21b1cd..361d8f5551 100644 --- a/_ru/overviews/collections-2.13/overview.md +++ b/_ru/overviews/collections-2.13/overview.md @@ -1,18 +1,12 @@ --- layout: multipage-overview title: Изменяемые и Неизменяемые Коллекции - -discourse: true - partof: collections-213 overview-name: Collections - num: 2 previous-page: introduction next-page: trait-iterable - language: ru - --- В коллекциях Scala постоянно проводят различие между неизменяемыми и изменяемыми коллекциями. _Изменяемые_ (mutable) коллекции могут быть изменены или дополнены. Это означает, что вы можете изменять, добавлять или удалять её элементы. _Неизменяемые_ (Immutable) коллекции, напротив, никогда не меняются. У них есть операции, имитирующие добавления, удаления или обновления, но эти операции каждый раз будут возвращать новую коллекцию и оставлять старую коллекцию без изменений. diff --git a/_ru/overviews/collections-2.13/performance-characteristics.md b/_ru/overviews/collections-2.13/performance-characteristics.md index 526a74a2b2..eb63206c02 100644 --- a/_ru/overviews/collections-2.13/performance-characteristics.md +++ b/_ru/overviews/collections-2.13/performance-characteristics.md @@ -1,18 +1,12 @@ --- layout: multipage-overview title: Показатели производительности - -discourse: true - partof: collections-213 overview-name: Collections - num: 12 previous-page: strings next-page: equality - language: ru - --- Из предыдущих объяснений стало ясно, что разные типы коллекций имеют разные показатели производительности. Что зачастую является основной причиной, выбора одной коллекции вместо другой. Показатели для наиболее распространенных операций собраны в таблицах ниже. diff --git a/_ru/overviews/collections-2.13/seqs.md b/_ru/overviews/collections-2.13/seqs.md index c5557bdd40..9bf9d180c3 100644 --- a/_ru/overviews/collections-2.13/seqs.md +++ b/_ru/overviews/collections-2.13/seqs.md @@ -1,18 +1,12 @@ --- layout: multipage-overview title: Последовательности. Трейт Seq, IndexedSeq и LinearSeq - -discourse: true - partof: collections-213 overview-name: Collections - num: 5 previous-page: trait-iterable next-page: sets - language: ru - --- Трейт [Seq](https://www.scala-lang.org/api/current/scala/collection/Seq.html) представляет из себя последовательность. Последовательность - это своего рода итерируемая сущность, у которой есть длина (`length`) и элементы с фиксированным индексом, начинающийся от `0`. diff --git a/_ru/overviews/collections-2.13/sets.md b/_ru/overviews/collections-2.13/sets.md index 3a2bbbf98e..2a4d4a0550 100644 --- a/_ru/overviews/collections-2.13/sets.md +++ b/_ru/overviews/collections-2.13/sets.md @@ -1,18 +1,12 @@ --- layout: multipage-overview title: Множества - -discourse: true - partof: collections-213 overview-name: Collections - num: 6 previous-page: seqs next-page: maps - language: ru - --- Множества (`Set`) - это итерируемые сущности, которые не содержат дублирующих друг друга элементов. Операции с множествами описаны в таблицах ниже. Описания включают операции для базовых, неизменяемых и изменяемых множеств. Все их операции поделены на следующие категории: diff --git a/_ru/overviews/collections-2.13/strings.md b/_ru/overviews/collections-2.13/strings.md index 1527860415..17e13d1a14 100644 --- a/_ru/overviews/collections-2.13/strings.md +++ b/_ru/overviews/collections-2.13/strings.md @@ -1,18 +1,12 @@ --- layout: multipage-overview title: Строки - -discourse: true - partof: collections-213 overview-name: Collections - num: 11 previous-page: arrays next-page: performance-characteristics - language: ru - --- Как и массивы, строки не являются непосредственно последовательностями, но могут быть преобразованы в них, а также поддерживают все операции которые есть у последовательностей. Ниже приведены некоторые примеры операций, которые можно вызывать на строках. diff --git a/_ru/overviews/collections-2.13/trait-iterable.md b/_ru/overviews/collections-2.13/trait-iterable.md index 25cfd6ed37..447859daba 100644 --- a/_ru/overviews/collections-2.13/trait-iterable.md +++ b/_ru/overviews/collections-2.13/trait-iterable.md @@ -1,18 +1,12 @@ --- layout: multipage-overview title: Трейт Iterable - -discourse: true - partof: collections-213 overview-name: Collections - num: 4 previous-page: overview next-page: seqs - language: ru - --- На самом верху иерархии коллекций находится трейт `Iterable`. Все методы в этого трейта описаны как абстрактные, `iterator` - это метод, который выдает элементы коллекции один за другим. diff --git a/_ru/overviews/collections-2.13/views.md b/_ru/overviews/collections-2.13/views.md index 8a095c96a1..3b8a5f5d76 100644 --- a/_ru/overviews/collections-2.13/views.md +++ b/_ru/overviews/collections-2.13/views.md @@ -1,18 +1,12 @@ --- layout: multipage-overview title: Отображения - -discourse: true - partof: collections-213 overview-name: Collections - num: 14 previous-page: equality next-page: iterators - language: ru - --- У коллекций довольно много вариантов создания новых коллекций. Ну например используя операции `map`, `filter` или `++`. Мы называем такие операции *трансформерами*, потому что они берут хотя бы одну коллекцию и трансформируют её в новую коллекцию. diff --git a/_ru/overviews/collections/introduction.md b/_ru/overviews/collections/introduction.md index 4f503f94d6..5b996a9254 100644 --- a/_ru/overviews/collections/introduction.md +++ b/_ru/overviews/collections/introduction.md @@ -1,14 +1,9 @@ --- layout: multipage-overview title: Введение - -discourse: false - partof: collections overview-name: Collections - num: 1 - language: ru --- diff --git a/_ru/overviews/parallel-collections/architecture.md b/_ru/overviews/parallel-collections/architecture.md index 5ee10d99b9..9677440e9c 100644 --- a/_ru/overviews/parallel-collections/architecture.md +++ b/_ru/overviews/parallel-collections/architecture.md @@ -1,9 +1,6 @@ --- layout: multipage-overview title: Архитектура библиотеки параллельных коллекций - -discourse: false - partof: parallel-collections overview-name: Parallel Collections diff --git a/_ru/overviews/parallel-collections/concrete-parallel-collections.md b/_ru/overviews/parallel-collections/concrete-parallel-collections.md index ab41a576c7..b6170ffe1d 100644 --- a/_ru/overviews/parallel-collections/concrete-parallel-collections.md +++ b/_ru/overviews/parallel-collections/concrete-parallel-collections.md @@ -1,12 +1,8 @@ --- layout: multipage-overview title: Конкретные классы параллельных коллекций - -discourse: false - partof: parallel-collections overview-name: Parallel Collections - language: ru num: 2 --- diff --git a/_ru/overviews/parallel-collections/configuration.md b/_ru/overviews/parallel-collections/configuration.md index 5dbd2b1e38..253c4c30d5 100644 --- a/_ru/overviews/parallel-collections/configuration.md +++ b/_ru/overviews/parallel-collections/configuration.md @@ -1,12 +1,8 @@ --- layout: multipage-overview title: Конфигурирование параллельных коллекций - -discourse: false - partof: parallel-collections overview-name: Parallel Collections - language: ru num: 7 --- diff --git a/_ru/overviews/parallel-collections/conversions.md b/_ru/overviews/parallel-collections/conversions.md index 114f2d8986..f001762841 100644 --- a/_ru/overviews/parallel-collections/conversions.md +++ b/_ru/overviews/parallel-collections/conversions.md @@ -1,12 +1,8 @@ --- layout: multipage-overview title: Преобразования параллельных коллекций - -discourse: false - partof: parallel-collections overview-name: Parallel Collections - language: ru num: 3 --- diff --git a/_ru/overviews/parallel-collections/ctries.md b/_ru/overviews/parallel-collections/ctries.md index 9e52d407bf..640ac7e8b9 100644 --- a/_ru/overviews/parallel-collections/ctries.md +++ b/_ru/overviews/parallel-collections/ctries.md @@ -1,12 +1,8 @@ --- layout: multipage-overview title: Многопоточные префиксные деревья - -discourse: false - partof: parallel-collections overview-name: Parallel Collections - language: ru num: 4 --- diff --git a/_ru/overviews/parallel-collections/custom-parallel-collections.md b/_ru/overviews/parallel-collections/custom-parallel-collections.md index 6fd6fa9f58..4dbcdf7e96 100644 --- a/_ru/overviews/parallel-collections/custom-parallel-collections.md +++ b/_ru/overviews/parallel-collections/custom-parallel-collections.md @@ -1,12 +1,8 @@ --- layout: multipage-overview title: Создание пользовательской параллельной коллекции - -discourse: false - partof: parallel-collections overview-name: Parallel Collections - language: ru num: 6 --- diff --git a/_ru/overviews/parallel-collections/overview.md b/_ru/overviews/parallel-collections/overview.md index 2d68d91d8d..e2b4bbcd7d 100644 --- a/_ru/overviews/parallel-collections/overview.md +++ b/_ru/overviews/parallel-collections/overview.md @@ -1,12 +1,8 @@ --- layout: multipage-overview title: Обзор - -discourse: false - partof: parallel-collections overview-name: Parallel Collections - num: 1 language: ru --- diff --git a/_ru/overviews/parallel-collections/performance.md b/_ru/overviews/parallel-collections/performance.md index b86e90bc2c..64e533e359 100644 --- a/_ru/overviews/parallel-collections/performance.md +++ b/_ru/overviews/parallel-collections/performance.md @@ -1,12 +1,8 @@ --- layout: multipage-overview title: Измерение производительности - -discourse: false - partof: parallel-collections overview-name: Parallel Collections - num: 8 language: ru --- diff --git a/_ru/tour/abstract-type-members.md b/_ru/tour/abstract-type-members.md index 849286419f..6da748d090 100644 --- a/_ru/tour/abstract-type-members.md +++ b/_ru/tour/abstract-type-members.md @@ -1,9 +1,6 @@ --- layout: tour title: Члены Абстрактного Типа - -discourse: true - partof: scala-tour num: 23 language: ru @@ -11,7 +8,6 @@ next-page: compound-types previous-page: inner-classes topics: abstract type members prerequisite-knowledge: variance, upper-type-bound - --- Абстрактные типы, такие как трейты и абстрактные классы, могут содержать членов абстрактного типа. diff --git a/_ru/tour/annotations.md b/_ru/tour/annotations.md index 99a668acb0..46718f2d77 100644 --- a/_ru/tour/annotations.md +++ b/_ru/tour/annotations.md @@ -1,16 +1,11 @@ --- layout: tour title: Аннотации - -discourse: true - partof: scala-tour - num: 32 language: ru next-page: packages-and-imports previous-page: by-name-parameters - --- Аннотации используются для передачи метаданных при объявлении. Например, аннотация `@deprecated` перед объявлением метода, заставит компилятор вывести предупреждение, если этот метод будет использован. diff --git a/_ru/tour/automatic-closures.md b/_ru/tour/automatic-closures.md index 7de83279d8..7465e6abef 100644 --- a/_ru/tour/automatic-closures.md +++ b/_ru/tour/automatic-closures.md @@ -1,8 +1,6 @@ --- layout: tour title: Конструкция Автоматического Замыкания Зависимого Типа - -discourse: true language: ru partof: scala-tour num: 14 diff --git a/_ru/tour/basics.md b/_ru/tour/basics.md index f6c3788f4c..518662c9f6 100644 --- a/_ru/tour/basics.md +++ b/_ru/tour/basics.md @@ -1,16 +1,11 @@ --- layout: tour title: Основы - -discourse: true - partof: scala-tour - num: 2 language: ru next-page: unified-types previous-page: tour-of-scala - --- На этой странице мы расскажем об основах Scala. diff --git a/_ru/tour/by-name-parameters.md b/_ru/tour/by-name-parameters.md index 4a1a4d4417..3be9478fe8 100644 --- a/_ru/tour/by-name-parameters.md +++ b/_ru/tour/by-name-parameters.md @@ -1,16 +1,11 @@ --- layout: tour title: Вызов по имени - -discourse: true - partof: scala-tour - num: 31 language: ru next-page: annotations previous-page: operators - --- _Вызов параметров по имени_ - это когда значение параметра вычисляется только в момент вызова параметра. Этот способ противоположен _вызову по значению_. Чтоб вызов параметра был по имени, необходимо просто указать `=>` перед его типом. diff --git a/_ru/tour/case-classes.md b/_ru/tour/case-classes.md index 9a49c560dd..64fab9024e 100644 --- a/_ru/tour/case-classes.md +++ b/_ru/tour/case-classes.md @@ -1,17 +1,12 @@ --- layout: tour title: Классы Образцы - -discourse: true - partof: scala-tour - num: 11 language: ru next-page: pattern-matching previous-page: multiple-parameter-lists prerequisite-knowledge: classes, basics, mutability - --- Классы образцы (Case classes) похожи на обычные классы с несколькими ключевыми отличиями, о которых мы поговорим ниже. Классы образцы хороши для моделирования неизменяемых данных. На следующей странице обзора вы увидите, насколько они полезны для участия в [сопоставлении с примером](pattern-matching.html). diff --git a/_ru/tour/classes.md b/_ru/tour/classes.md index db66150841..d7e66a84c0 100644 --- a/_ru/tour/classes.md +++ b/_ru/tour/classes.md @@ -1,18 +1,13 @@ --- layout: tour title: Классы - -discourse: true - partof: scala-tour - num: 4 language: ru next-page: traits previous-page: unified-types topics: classes prerequisite-knowledge: no-return-keyword, type-declaration-syntax, string-interpolation, procedures - --- Классы в Scala являются основами для создания объектов. Они могут содержать методы, константы, переменные, типы, объекты, трейты и классы, которые в совокупности называются _членами_. Типы, объекты и трейты будут рассмотрены позже в ходе нашего обзора. diff --git a/_ru/tour/compound-types.md b/_ru/tour/compound-types.md index eb861afbfd..5d0a49aa0e 100644 --- a/_ru/tour/compound-types.md +++ b/_ru/tour/compound-types.md @@ -1,16 +1,11 @@ --- layout: tour title: Составные Типы - -discourse: true - partof: scala-tour - num: 24 language: ru next-page: self-types previous-page: abstract-type-members - --- Иногда необходимо выразить, то что тип объекта является подтипом нескольких других типов. В Scala это можно выразить с помощью *составных типов*, которые являются объединением нескольких типов объектов. diff --git a/_ru/tour/default-parameter-values.md b/_ru/tour/default-parameter-values.md index 72ab55e786..ac8c04eda4 100644 --- a/_ru/tour/default-parameter-values.md +++ b/_ru/tour/default-parameter-values.md @@ -1,17 +1,12 @@ --- layout: tour title: Значения Параметров По умолчанию - -discourse: true - partof: scala-tour - num: 33 language: ru next-page: named-arguments previous-page: classes prerequisite-knowledge: named-arguments, function syntax - --- Scala предоставляет возможность задавать значения параметров по умолчанию, что позволяет лишний раз не указывать параметры. diff --git a/_ru/tour/extractor-objects.md b/_ru/tour/extractor-objects.md index 0c968f36cd..8d86b454ac 100644 --- a/_ru/tour/extractor-objects.md +++ b/_ru/tour/extractor-objects.md @@ -1,16 +1,11 @@ --- layout: tour title: Объект Экстрактор - -discourse: true - partof: scala-tour - num: 16 language: ru next-page: for-comprehensions previous-page: regular-expression-patterns - --- Объект Экстрактор (объект распаковщик или extractor object) - это объект с методом `unapply`. В то время как метод `apply` обычно действует как конструктор, который принимает аргументы и создает объект, метод `unapply` действует обратным образом, он принимает объект и пытается извлечь и вернуть аргументы из которых он (возможно) был создан. Чаще всего этот метод используется в функциях сопоставления с примером и в частично определенных функциях. diff --git a/_ru/tour/for-comprehensions.md b/_ru/tour/for-comprehensions.md index 29aad7105c..5a2c538769 100644 --- a/_ru/tour/for-comprehensions.md +++ b/_ru/tour/for-comprehensions.md @@ -1,16 +1,11 @@ --- layout: tour title: Сложные for-выражения - -discourse: true - partof: scala-tour - num: 17 language: ru next-page: generic-classes previous-page: extractor-objects - --- Scala предлагает простую запись для выражения *последовательных преобразований*. Эти преобразования можно упростить используя специальный синтаксис `for выражения` (for comprehension), который записывается как `for (enumerators) yield e`, где `enumerators` относятся к списку перечислителей, разделенных точкой с запятой. Где отдельный такой "перечислитель" (*enumerator*) является либо генератором, который вводит новые переменные, либо фильтром. For-выражение вычисляет тело `e` (которое связанно с тем что генерирует *enumerator*) и возвращает последовательность вычислений. diff --git a/_ru/tour/generic-classes.md b/_ru/tour/generic-classes.md index fafc2fd13e..48d68a9733 100644 --- a/_ru/tour/generic-classes.md +++ b/_ru/tour/generic-classes.md @@ -1,17 +1,12 @@ --- layout: tour title: Обобщенные Классы - -discourse: true - partof: scala-tour - num: 18 language: ru next-page: variances previous-page: for-comprehensions assumed-knowledge: classes unified-types - --- Обобщенные классы (Generic classes) - это классы, обладающие параметрическим полиморфизмом (т. е. классы, которые изменяют свое поведение в зависимости от приписываемого им типа. Этот тип указывается в квадратных скобках `[]` сразу после имени класса). Они особенно полезны для создания коллекций. diff --git a/_ru/tour/higher-order-functions.md b/_ru/tour/higher-order-functions.md index 36a8f0a2a7..2b029a6ca1 100644 --- a/_ru/tour/higher-order-functions.md +++ b/_ru/tour/higher-order-functions.md @@ -1,16 +1,11 @@ --- layout: tour title: Функции Высшего Порядка - -discourse: true - partof: scala-tour - num: 8 language: ru next-page: nested-functions previous-page: mixin-class-composition - --- Функции высшего порядка могут принимать другие функции в качестве параметров или возвращать функцию в качестве результата. diff --git a/_ru/tour/implicit-conversions.md b/_ru/tour/implicit-conversions.md index bd36a9e749..02c5319fae 100644 --- a/_ru/tour/implicit-conversions.md +++ b/_ru/tour/implicit-conversions.md @@ -1,16 +1,11 @@ --- layout: tour title: Неявные Преобразования - -discourse: true - partof: scala-tour - num: 27 language: ru next-page: polymorphic-methods previous-page: implicit-parameters - --- Неявные преобразование типа `S` к типу `T` задается неявным значением функционального типа `S =>T`, или неявным методом, который способен преобразовывать к значению требуемого типа. diff --git a/_ru/tour/implicit-parameters.md b/_ru/tour/implicit-parameters.md index cf58ded10e..f6ca9b6fda 100644 --- a/_ru/tour/implicit-parameters.md +++ b/_ru/tour/implicit-parameters.md @@ -1,16 +1,11 @@ --- layout: tour title: Неявные Параметры - -discourse: true - partof: scala-tour - num: 26 language: ru next-page: implicit-conversions previous-page: self-types - --- Метод может иметь список _неявных_ параметров, помеченный ключевым словом _implicit_ в начале списка параметров. Если параметры в этом списке не передаются как обычно, то Scala будет искать, где можно получить неявное значение требуемого типа, и если найдет, то передаст его автоматически. diff --git a/_ru/tour/inner-classes.md b/_ru/tour/inner-classes.md index 736677ceff..9d86b84000 100644 --- a/_ru/tour/inner-classes.md +++ b/_ru/tour/inner-classes.md @@ -1,16 +1,11 @@ --- layout: tour title: Внутренние классы - -discourse: true - partof: scala-tour - num: 22 language: ru next-page: abstract-type-members previous-page: lower-type-bounds - --- В Scala классам можно иметь в качестве членов другие классы. В отличие от Java-подобных языков, где такие внутренние классы являются членами окружающего класса, в Scala такие внутренние классы привязаны к содержащему его объекту. Предположим, мы хотим, чтобы компилятор не позволял нам на этапе компиляции смешивать узлы этого графа. Для решения этой задачи нам подойдут типы, зависящие от своего расположения. diff --git a/_ru/tour/lower-type-bounds.md b/_ru/tour/lower-type-bounds.md index 8351695a72..ac9e08bd59 100644 --- a/_ru/tour/lower-type-bounds.md +++ b/_ru/tour/lower-type-bounds.md @@ -1,17 +1,12 @@ --- layout: tour title: Нижнее Ограничение Типа - -discourse: true - partof: scala-tour - num: 21 language: ru next-page: inner-classes previous-page: upper-type-bounds prerequisite-knowledge: upper-type-bounds, generics, variance - --- В то время как [верхнее ограничение типа](upper-type-bounds.html) ограничивает тип до подтипа стороннего типа, *нижнее ограничение типа* объявляют тип супертипом стороннего типа. Термин `B >: A` выражает, то что параметр типа `B` или абстрактный тип `B` относится к супертипу типа `A`. В большинстве случаев `A` будет задавать тип класса, а `B` задавать тип метода. diff --git a/_ru/tour/mixin-class-composition.md b/_ru/tour/mixin-class-composition.md index ff7c1d60d9..c27a2edea1 100644 --- a/_ru/tour/mixin-class-composition.md +++ b/_ru/tour/mixin-class-composition.md @@ -1,17 +1,12 @@ --- layout: tour title: Композиция классов с примесями - -discourse: true - partof: scala-tour - num: 7 language: ru next-page: higher-order-functions previous-page: tuples prerequisite-knowledge: inheritance, traits, abstract-classes, unified-types - --- Примеси (Mixin) - это трейты, которые используются для создания класса. diff --git a/_ru/tour/multiple-parameter-lists.md b/_ru/tour/multiple-parameter-lists.md index c4656f5193..c93a6e31d1 100644 --- a/_ru/tour/multiple-parameter-lists.md +++ b/_ru/tour/multiple-parameter-lists.md @@ -1,16 +1,11 @@ --- layout: tour title: Множественные списки параметров (Каррирование) - -discourse: true - partof: scala-tour - num: 10 language: ru next-page: case-classes previous-page: nested-functions - --- Методы могут объявляться с несколькими списками параметров. При этом когда такой метод вызывается с меньшим количеством списков параметров, это приводит к созданию новой функции, которая ожидает на вход не достающий список параметров. Формально это называется [частичное применение](https://en.wikipedia.org/wiki/Partial_application). diff --git a/_ru/tour/named-arguments.md b/_ru/tour/named-arguments.md index 32b83664e4..463480e547 100644 --- a/_ru/tour/named-arguments.md +++ b/_ru/tour/named-arguments.md @@ -1,17 +1,12 @@ --- layout: tour title: Именованные Аргументы - -discourse: true - partof: scala-tour - num: 34 language: ru next-page: packages-and-imports previous-page: default-parameter-values prerequisite-knowledge: function-syntax - --- При вызове методов можно конкретно указывать название задаваемого аргумента следующим образом: diff --git a/_ru/tour/nested-functions.md b/_ru/tour/nested-functions.md index 663e0fdc36..6a59ca5a0e 100644 --- a/_ru/tour/nested-functions.md +++ b/_ru/tour/nested-functions.md @@ -1,16 +1,11 @@ --- layout: tour title: Вложенные Методы - -discourse: true - partof: scala-tour - num: 9 language: ru next-page: multiple-parameter-lists previous-page: higher-order-functions - --- В Scala возможно объявление метода вкладывать в тело другого метода. Это реализовано в следующем примере, в котором метод `factorial` используется для вычисления факториала заданного числа: diff --git a/_ru/tour/operators.md b/_ru/tour/operators.md index 09ea35ea76..dd80f7905d 100644 --- a/_ru/tour/operators.md +++ b/_ru/tour/operators.md @@ -1,17 +1,12 @@ --- layout: tour title: Операторы - -discourse: true - partof: scala-tour - num: 30 language: ru next-page: by-name-parameters previous-page: type-inference prerequisite-knowledge: case-classes - --- В Скале операторы - это обычные методы. В качестве _инфиксного оператора_ может быть использован любой метод с одним параметром. Например, `+` может вызываться с использованием точки: ``` diff --git a/_ru/tour/package-objects.md b/_ru/tour/package-objects.md index 1a0ba1b7f2..e7924e8de8 100644 --- a/_ru/tour/package-objects.md +++ b/_ru/tour/package-objects.md @@ -1,11 +1,7 @@ --- layout: tour title: Объекты Пакета - -discourse: true - partof: scala-tour - num: 36 language: ru previous-page: packages-and-imports diff --git a/_ru/tour/packages-and-imports.md b/_ru/tour/packages-and-imports.md index 2a3e6ba6ff..a4d6710454 100644 --- a/_ru/tour/packages-and-imports.md +++ b/_ru/tour/packages-and-imports.md @@ -1,11 +1,7 @@ --- layout: tour title: Пакеты и Импорт - -discourse: true - partof: scala-tour - num: 35 language: ru previous-page: annotations diff --git a/_ru/tour/pattern-matching.md b/_ru/tour/pattern-matching.md index 8d329636da..15e58ff983 100644 --- a/_ru/tour/pattern-matching.md +++ b/_ru/tour/pattern-matching.md @@ -1,17 +1,12 @@ --- layout: tour title: Сопоставление с примером - -discourse: true - partof: scala-tour - num: 12 language: ru next-page: singleton-objects previous-page: case-classes prerequisite-knowledge: case-classes, string-interpolation, subtyping - --- Сопоставление с примером (Pattern matching) - это механизм сравнения значений с определенным примером. При успешном совпадении значение может быть разложено на составные части. Мы рассматриваем сопоставление с примером, как более мощную версию `switch` оператора из Java. Eго также можно использовать вместо серии if/else выражений. diff --git a/_ru/tour/polymorphic-methods.md b/_ru/tour/polymorphic-methods.md index 3c017b89f6..9d54223100 100644 --- a/_ru/tour/polymorphic-methods.md +++ b/_ru/tour/polymorphic-methods.md @@ -1,17 +1,12 @@ --- layout: tour title: Полиморфные методы - -discourse: true - partof: scala-tour - num: 28 language: ru next-page: type-inference previous-page: implicit-conversions prerequisite-knowledge: unified-types - --- Также как и у обобщенных классов, у методов есть полиморфизм по типу, с таким же синтаксисом (параметр типа указывается в квадратных скобках сразу после названия метода). diff --git a/_ru/tour/regular-expression-patterns.md b/_ru/tour/regular-expression-patterns.md index e8c2ea8404..159921587c 100644 --- a/_ru/tour/regular-expression-patterns.md +++ b/_ru/tour/regular-expression-patterns.md @@ -1,16 +1,11 @@ --- layout: tour title: Регулярные Выражения - -discourse: true - partof: scala-tour - num: 15 language: ru next-page: extractor-objects previous-page: singleton-objects - --- Регулярные выражения (Regular expression) - это специальный шаблон для поиска данных, задаваемый в виде текстовой строки. Любая строка может быть преобразована в регулярное выражение методом `.r`. diff --git a/_ru/tour/self-types.md b/_ru/tour/self-types.md index 2ce9946450..5ca4c91b22 100644 --- a/_ru/tour/self-types.md +++ b/_ru/tour/self-types.md @@ -1,18 +1,13 @@ --- layout: tour title: Самоописываемые типы - -discourse: true - partof: scala-tour - num: 25 language: ru next-page: implicit-parameters previous-page: compound-types topics: self-types prerequisite-knowledge: nested-classes, mixin-class-composition - --- Самоописываемый тип(Self type) - это способ объявить, что трейт должен быть смешан с другим трейтом, даже если он не расширяет его напрямую. Что открывает доступ к членам зависимости без импортирования. diff --git a/_ru/tour/singleton-objects.md b/_ru/tour/singleton-objects.md index d39f5c170e..5b2f79dac8 100644 --- a/_ru/tour/singleton-objects.md +++ b/_ru/tour/singleton-objects.md @@ -1,11 +1,7 @@ --- layout: tour title: Объекты Одиночки - -discourse: true - partof: scala-tour - num: 13 language: ru next-page: regular-expression-patterns diff --git a/_ru/tour/tour-of-scala.md b/_ru/tour/tour-of-scala.md index ac523d9914..321685dbb3 100644 --- a/_ru/tour/tour-of-scala.md +++ b/_ru/tour/tour-of-scala.md @@ -1,11 +1,7 @@ --- layout: tour title: Введение - -discourse: true - partof: scala-tour - num: 1 language: ru next-page: basics diff --git a/_ru/tour/traits.md b/_ru/tour/traits.md index 3eec6fd35c..ab7f6a5ade 100644 --- a/_ru/tour/traits.md +++ b/_ru/tour/traits.md @@ -1,18 +1,13 @@ --- layout: tour title: Трейты - -discourse: true - partof: scala-tour - num: 5 language: ru next-page: tuples previous-page: named-arguments topics: traits prerequisite-knowledge: expressions, classes, generics, objects, companion-objects - --- Трейты (Traits) используются, чтобы обмениваться между классами информацией о структуре и полях. Они похожи на интерфейсы из Java 8. Классы и объекты могут расширять трейты, но трейты не могут быть созданы и поэтому не имеют параметров. diff --git a/_ru/tour/tuples.md b/_ru/tour/tuples.md index 8d30c607c5..8af61d5102 100644 --- a/_ru/tour/tuples.md +++ b/_ru/tour/tuples.md @@ -1,17 +1,12 @@ --- layout: tour title: Кортежи - -discourse: true - partof: scala-tour - num: 6 language: ru next-page: mixin-class-composition previous-page: traits topics: tuples - --- В Scala, кортеж (Тuple) это класс контейнер содержащий упорядоченный набор элементов различного типа. diff --git a/_ru/tour/type-inference.md b/_ru/tour/type-inference.md index 5e5e39cf17..6709acf411 100644 --- a/_ru/tour/type-inference.md +++ b/_ru/tour/type-inference.md @@ -1,11 +1,7 @@ --- layout: tour title: Выведение Типа - -discourse: true - partof: scala-tour - num: 29 language: ru next-page: operators diff --git a/_ru/tour/unified-types.md b/_ru/tour/unified-types.md index 1bd87556b7..7399f82409 100644 --- a/_ru/tour/unified-types.md +++ b/_ru/tour/unified-types.md @@ -1,17 +1,12 @@ --- layout: tour title: Единобразие типов - -discourse: true - partof: scala-tour - num: 3 language: ru next-page: classes previous-page: basics prerequisite-knowledge: classes, basics - --- В Scala все значения имеют тип, включая числовые значения и функции. Диаграмма ниже иллюстрирует подмножество иерархии типов. diff --git a/_ru/tour/upper-type-bounds.md b/_ru/tour/upper-type-bounds.md index 60ca550d59..2bfe19f96e 100644 --- a/_ru/tour/upper-type-bounds.md +++ b/_ru/tour/upper-type-bounds.md @@ -1,16 +1,12 @@ --- layout: tour title: Верхнее Ограничение Типа - -discourse: true - partof: scala-tour categories: tour num: 20 language: ru next-page: lower-type-bounds previous-page: variances - --- В Scala [параметры типа](generic-classes.html) и [члены абстрактного типа](abstract-type-members.html) могут быть ограничены определенными диапазонами. Такие диапазоны ограничивают конкретные значение типа и, возможно, предоставляют больше информации о членах таких типов. _Верхнее ограничение типа_ `T <: A` указывает на то что тип `T` относится к подтипу типа `A`. diff --git a/_ru/tour/variances.md b/_ru/tour/variances.md index c59549f340..17dd06b74c 100644 --- a/_ru/tour/variances.md +++ b/_ru/tour/variances.md @@ -1,16 +1,11 @@ --- layout: tour title: Вариантность - -discourse: true - partof: scala-tour - num: 19 language: ru next-page: upper-type-bounds previous-page: generic-classes - --- Вариантность (Variances) - это указание определенной специфики взаимосвязи между связанными типам. Scala поддерживает вариантную аннотацию типов у [обобщенных классов](generic-classes.html), что позволяет им быть ковариантными, контрвариантными или инвариантными (если нет никакого указание на вариантность). Использование вариантности в системе типов позволяет устанавливать понятные взаимосвязи между сложными типами, в то время как отсутствие вариантности может ограничить повторное использование абстракции класса. From 86b753a7c61b9ef04013902b6104eb92439b38fd Mon Sep 17 00:00:00 2001 From: Philippus Date: Tue, 19 Apr 2022 08:47:50 +0200 Subject: [PATCH 1841/3075] Display code blocks inside details/summary correctly --- _overviews/scala3-macros/tutorial/inline.md | 12 ++++++++++-- _sass/layout/details-summary.scss | 3 +++ resources/css/style.scss | 1 + 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 _sass/layout/details-summary.scss diff --git a/_overviews/scala3-macros/tutorial/inline.md b/_overviews/scala3-macros/tutorial/inline.md index c081b8d61c..30c445cef0 100644 --- a/_overviews/scala3-macros/tutorial/inline.md +++ b/_overviews/scala3-macros/tutorial/inline.md @@ -254,8 +254,11 @@ Calling `power` with statically known constants results in the following code: val x = 2 power(x * x, 1) ``` + +{::options parse_block_html="true" /}
- See rest of inlining steps + See rest of inlining steps + ```scala // then inlined as @@ -283,6 +286,8 @@ x2 * 1.0 ```
+{::options parse_block_html="false" /} + In contrast, let us imagine we do not know the value of `n`: ```scala @@ -291,8 +296,10 @@ power(2, unknownNumber) Driven by the inline annotation on the parameter, the compiler will try to unroll the recursion. But without any success, since the parameter is not statically known. +{::options parse_block_html="true" /}
- See inlining steps + See inlining steps + ```scala // first inlines as @@ -318,6 +325,7 @@ else { ... ```
+{::options parse_block_html="false" /} To guarantee that the branching can indeed be performed at compile-time, we can use the `inline if` variant of `if`. Annotating a conditional with `inline` will guarantee that the conditional can be reduced at compile-time and emits an error if the condition is not a statically known constant. diff --git a/_sass/layout/details-summary.scss b/_sass/layout/details-summary.scss new file mode 100644 index 0000000000..1f18d4cd64 --- /dev/null +++ b/_sass/layout/details-summary.scss @@ -0,0 +1,3 @@ +details > summary > p { + display: inline; +} diff --git a/resources/css/style.scss b/resources/css/style.scss index 57b121deba..fb5c150296 100755 --- a/resources/css/style.scss +++ b/resources/css/style.scss @@ -56,6 +56,7 @@ @import 'layout/blog'; @import 'layout/download'; @import 'layout/content-contributors'; // COMPONENTS +@import 'layout/details-summary'; //------------------------------------------------ //------------------------------------------------ @import 'components/buttons'; From c4c0be187b9caf2c5243da2a2b521e91efba2ef2 Mon Sep 17 00:00:00 2001 From: Erik van Oosten Date: Thu, 21 Apr 2022 14:54:35 +0200 Subject: [PATCH 1842/3075] Avoid dysphemisms I was reading the inclusive language guide at https://docs.scala-lang.org/contribute/inclusive-language-guide.html. I have 2 points of feedback. I initially posted this on Discord but then I noticed I could do a pull request. So here it is. Re. blacklist/whitelist. Such lists are often used to regulate access. Therefore I propose we suggest the alternative 'allowlist/denylist' as it is probably appropriate in more circumstances. This is also the suggestion done from the linked page https://github.com/dialpad/inclusive-language. --- _overviews/contribute/inclusive-language-guide.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/_overviews/contribute/inclusive-language-guide.md b/_overviews/contribute/inclusive-language-guide.md index 375d988158..5689979302 100644 --- a/_overviews/contribute/inclusive-language-guide.md +++ b/_overviews/contribute/inclusive-language-guide.md @@ -90,7 +90,7 @@ This list is neither comprehensive nor definitive, and it can evolve over time. * **blacklist/whitelist** \ While the etymology of these words has no relation to racism, their use suggests an association between the color black and some form of badness or exclusion, and between the color white and some form of goodness or inclusion. Prefer alternatives when possible. - Several alternatives have been proposed but none sticks as "the one". We suggest using the pair *excludelist*/*includelist*, as it is generic enough to replace all uses of *blacklist*/*whitelist*. + Several alternatives have been proposed but none sticks as "the one". We suggest using the pair *allowlist*/*denylist*, as it is generic enough to replace most uses of *blacklist*/*whitelist*. * **master/slave** \ Never use *slave*. Never use *master* in conjunction with *slave*. @@ -116,6 +116,12 @@ We encourage you to research inclusive language guidelines applicable to your do You may want to use automated software like [In Solidarity](https://github.com/apps/in-solidarity) to steer contributors away from loaded words. +## Dysphemism + +Dysphemisms, the opposite of euphemisms, should be avoided. For example, the English expressions "pull the trigger" (enforce a decision) and "bite the bullet" (endure hardship) can be disturbingly violent if you are not used to them. + +Using the direct meaning is preferred. + ## Backward compatibility Sometimes, we have existing code, APIs or commands that do not follow the above recommendations. From 99d4d45e3c58c988849a1439a83e8f69a155a295 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Chantepie?= Date: Thu, 21 Apr 2022 21:25:45 +0200 Subject: [PATCH 1843/3075] Fix StandardPlugin example --- _scala3-reference/changed-features/compiler-plugins.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_scala3-reference/changed-features/compiler-plugins.md b/_scala3-reference/changed-features/compiler-plugins.md index c77796d71d..39358b4e8c 100644 --- a/_scala3-reference/changed-features/compiler-plugins.md +++ b/_scala3-reference/changed-features/compiler-plugins.md @@ -57,6 +57,7 @@ package dividezero import dotty.tools.dotc.ast.Trees.* import dotty.tools.dotc.ast.tpd +import dotty.tools.dotc.report import dotty.tools.dotc.core.Constants.Constant import dotty.tools.dotc.core.Contexts.Context import dotty.tools.dotc.core.Decorators.* @@ -84,7 +85,7 @@ class DivideZeroPhase extends PluginPhase: tree match case Apply(Select(rcvr, nme.DIV), List(Literal(Constant(0)))) if rcvr.tpe <:< defn.IntType => - report.error("dividing by zero", tree.pos) + report.error("dividing by zero", tree.srcPos) case _ => () tree From 885fac887ecff3a2964c095af6cd5b8e05782180 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=A6=E5=A2=83=E8=BF=B7=E7=A6=BB?= Date: Fri, 22 Apr 2022 23:48:15 +0800 Subject: [PATCH 1844/3075] fix --- _zh-cn/scala3/new-in-scala3.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/_zh-cn/scala3/new-in-scala3.md b/_zh-cn/scala3/new-in-scala3.md index 472f66331f..ed649cb7da 100644 --- a/_zh-cn/scala3/new-in-scala3.md +++ b/_zh-cn/scala3/new-in-scala3.md @@ -36,7 +36,7 @@ Scala的一个基本核心概念是(在某种程度上仍然是)为用户提 - **Viewing one type as another**. [隐式转换][contextual-conversions]已经被重新设计为类型类`Conversion`的实例。 -- **Higher-order contextual abstractions**. [context functions][contextual-functions]的 _全新_ 功能使上下文抽象成为一流的公民。它们是库开发人员的一个重要工具,允许表达简洁的特定领域语言。 +- **Higher-order contextual abstractions**. [context functions][contextual-functions]的 _全新_ 功能使上下文抽象成为第一等公民。它们是库开发人员的一个重要工具,允许表达简洁的特定领域语言。 - **Actionable feedback from the compiler**. 如果一个隐式参数不能被编译器解决,它现在提供了可能解决这个问题的[import suggestions](https://www.scala-lang.org/blog/2020/05/05/scala-3-import-suggestions.html)。 @@ -47,17 +47,17 @@ Scala的一个基本核心概念是(在某种程度上仍然是)为用户提 - **Opaque Types**. 将实现细节隐藏在[opaque type aliases][types-opaque]的别名后面,而不需要在性能上付出代价! Opaque types 取代了值类,并允许你建立一个抽象的屏障,而不会造成额外的装箱开销。 -- **Intersection and union types**. 将类型系统建立在新的基础上,导致了新的类型系统功能的引入:[intersection types][types-intersection]的实例,如`A & B`,既是`A`的实例,也是`B`的实例;[union types][types-union]的实例,如`A | B`,是`A`或`B`的实例。这两种结构都允许程序员在继承层次结构之外灵活地表达类型约束。 +- **Intersection and union types**. 将类型系统建立在新的基础上,引入了新的类型系统特性:[intersection types][types-intersection]的实例,如`A & B`,既是`A`的实例,也是`B`的实例;[union types][types-union]的实例,如`A | B`,是`A`或`B`的实例。这两种结构都允许程序员在继承层次结构之外灵活地表达类型约束。 - **Dependent function types**. Scala 2 已经允许返回类型依赖于(值)参数。在 Scala 3 中,现在可以对这种模式进行抽象,表达[dependent function types][types-dependent]。在类型`F = (e: Entry) => e.Key`中,结果类型取决于参数。 - **Polymorphic function types**. 与 dependent function types 一样,Scala 2 支持拥有类型参数的方法,但不允许程序员对这些方法进行抽象。在 Scala 3 中,像`[A] => List[A] => List[A]`这样的[polymorphic function types][types-polymorphic]可以抽象出除值参数外还接受 _类型参数_ 的函数。 -- **Type lambdas**. 在 Scala 2 中需要用[编译器插件](https://github.com/typelevel/kind-projector)来表达的东西,现在在 Scala 3 中是第一类的功能:类型lambdas是类型级别的函数,可以作为(高等类型的)类型参数传递,而不需要辅助类型定义。 +- **Type lambdas**. 在 Scala 2 中需要用[编译器插件](https://github.com/typelevel/kind-projector)来表达的东西,现在在 Scala 3 中是原生支持的功能:类型lambdas是类型级别的函数,可以作为(高等类型的)类型参数传递,而不需要辅助类型定义。 - **Match types**. Scala 3 提供了对[matching on types][types-match]的直接支持,而不是使用隐式解析对类型级别的计算进行编码。将类型级计算整合到类型检查器中,可以改进错误信息,并消除对复杂编码的需求。 -### 重新设想的:面向对象的编程 +### Re-envisioned:面向对象的编程 Scala 一直处于函数式编程和面向对象编程的前沿 -- 而 Scala 3 在这两个方向上都推动了边界的发展! 上述类型系统的变化和上下文抽象的重新设计使得 _函数式编程_ 比以前更容易。同时,以下的新特性使结构良好的 _面向对象设计_ 成为可能,并支持最佳实践。 @@ -65,7 +65,7 @@ Scala 一直处于函数式编程和面向对象编程的前沿 -- 而 Scala 3 - **Plan for extension**. 在面向对象的设计中,扩展那些不打算扩展的类是一个长期存在的问题。为了解决这个问题,[open classes][oo-open]要求库设计者 _明确地_ 将类标记为 open(开放的)。 -- **Hide implementation details**. 实施行为的实用性traits有时不应该是推断类型的一部分。在 Scala 3 中,这些traits可以被标记为[transparent][oo-transparent],(在推断类型中)向用户隐藏继承性。 +- **Hide implementation details**. 实现功能的工具性的traits有时不应该是推断类型的一部分。在 Scala 3 中,这些traits可以被标记为[transparent][oo-transparent],(在推断类型中)向用户隐藏继承信息。 - **Composition over inheritance**. 这句话经常被引用,但实现起来却很繁琐。Scala 3 的[export clauses][oo-export]则不然:与imports对应,export clauses 允许用户为对象的选定成员定义别名。 @@ -74,13 +74,13 @@ Scala 一直处于函数式编程和面向对象编程的前沿 -- 而 Scala 3 ### Batteries Included: 元编程 Scala 2 中的宏只是一个实验性的功能,而 Scala 3 则为元编程提供了强大的工具库。[宏教程]({% link _overviews/scala3-macros/tutorial/index.md %})中包含了关于不同设施的详细信息。特别是,Scala 3 为元编程提供了以下功能: -- **Inline**. [inline feature][meta-inline]允许在编译时减少数值和方法。这个简单的功能已经涵盖了许多使用情况,同时也为更高级的功能提供了入口。 +- **Inline**. [inline feature][meta-inline]允许在编译时化简值和方法。这个简单的功能已经涵盖了许多使用情况,同时也为更高级的功能提供了入口。 - **Compile-time operations**. 包[`scala.compiletime`][meta-compiletime]中包含了额外的功能,可以用来实现内联方法。 - **Quoted code blocks**. Scala 3为代码增加了[quasi-quotation][meta-quotes]的新功能,这为构建和分析代码提供了方便的高级接口。构建加一加一的代码就像`'{ 1 + 1 }`一样简单。 - **Reflection API**. 对于更高级的用例,[quotes.reflect][meta-reflection]提供了更详细的控制来检查和生成程序树。 -如果你想进一步了解 Scala 3 中的元编程,我们邀请你参加[教程][meta-tutorial]。 +如果你想进一步了解 Scala 3 中的元编程,我们邀请你参阅我们的[教程][meta-tutorial]。 [enums]: {{ site.scala3ref }}/enums/enums.html [enums-adts]: {{ site.scala3ref }}/enums/adts.html From 6b6676f885d39e05e8be4eb4fc076d416366bb34 Mon Sep 17 00:00:00 2001 From: Maximilien Tirard Date: Sat, 23 Apr 2022 14:28:14 +0100 Subject: [PATCH 1845/3075] Typo --- _overviews/parallel-collections/performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/parallel-collections/performance.md b/_overviews/parallel-collections/performance.md index 625f08304e..96be271b44 100644 --- a/_overviews/parallel-collections/performance.md +++ b/_overviews/parallel-collections/performance.md @@ -81,7 +81,7 @@ For proper benchmark examples, you can see the source code inside [Scala library This is a question commonly asked. The answer is somewhat involved. -The size of the collection at which the parallelization pays of really +The size of the collection at which the parallelization pays off really depends on many factors. Some of them, but not all, include: - Machine architecture. Different CPU types have different From c09f64ad58eaf42a3f5619c434c9f3919f846124 Mon Sep 17 00:00:00 2001 From: kenji yoshida <6b656e6a69@gmail.com> Date: Sun, 24 Apr 2022 09:50:15 +0900 Subject: [PATCH 1846/3075] fix Scala 3 reflection doc. `companionObject` => `companionClass` https://github.com/lampepfl/dotty/blob/3.1.3-RC2/library/src/scala/quoted/Quotes.scala#L3929-L3933 --- _overviews/scala3-macros/tutorial/reflection.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_overviews/scala3-macros/tutorial/reflection.md b/_overviews/scala3-macros/tutorial/reflection.md index b9bca2e1c9..46618a1d4f 100644 --- a/_overviews/scala3-macros/tutorial/reflection.md +++ b/_overviews/scala3-macros/tutorial/reflection.md @@ -117,7 +117,7 @@ In addition, `Symbol` exposes and is used by many useful methods. For example: - `declaredFields` and `declaredMethods` allow you to iterate on the fields and members defined inside a symbol - `flags` allows you to check multiple properties of a symbol - - `companionObject` and `companionModule` provide a way to jump to and from the companion object/class + - `companionClass` and `companionModule` provide a way to jump to and from the companion object/class - `TypeRepr.baseClasses` returns the list of symbols of classes extended by a type - `Symbol.pos` gives you access to the position where the symbol is defined, the source code of the definition, and even the filename where the symbol is defined - many others that you can find in [`SymbolMethods`](https://scala-lang.org/api/3.x/scala/quoted/Quotes$reflectModule$SymbolMethods.html) From 0ac46fb75644b042c04bb9469f8951847331d1b0 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 29 Apr 2022 17:00:51 +0200 Subject: [PATCH 1847/3075] add tabs on get-started page (english) --- _config.yml | 3 + _data/setup-scala.yml | 4 + _includes/code-snippet.html | 6 ++ _includes/getting-started.md | 52 +++++----- _includes/tabsection.html | 20 ++++ _install_tabs/1-macos.md | 23 +++++ _install_tabs/2-linux.md | 14 +++ _install_tabs/3-windows.md | 14 +++ _install_tabs/4-other.md | 17 ++++ _sass/layout/alt-details.scss | 46 +++++++++ _sass/layout/scala-in-action.scss | 158 ++++++++++++++++++++++++++++++ _sass/layout/tabsection.scss | 60 ++++++++++++ resources/css/style.scss | 3 + resources/js/functions.js | 78 ++++++++++++--- 14 files changed, 456 insertions(+), 42 deletions(-) create mode 100644 _data/setup-scala.yml create mode 100644 _includes/code-snippet.html create mode 100644 _includes/tabsection.html create mode 100644 _install_tabs/1-macos.md create mode 100644 _install_tabs/2-linux.md create mode 100644 _install_tabs/3-windows.md create mode 100644 _install_tabs/4-other.md create mode 100644 _sass/layout/alt-details.scss create mode 100755 _sass/layout/scala-in-action.scss create mode 100755 _sass/layout/tabsection.scss diff --git a/_config.yml b/_config.yml index accb4b5df1..21f5c59539 100644 --- a/_config.yml +++ b/_config.yml @@ -21,6 +21,9 @@ scala-3-version: 3.1.2 collections: contribute_resources: + output: false + install_tabs: + output: false style: output: true overviews: diff --git a/_data/setup-scala.yml b/_data/setup-scala.yml new file mode 100644 index 0000000000..d1bb19a78d --- /dev/null +++ b/_data/setup-scala.yml @@ -0,0 +1,4 @@ +linux: curl -fL https://github.com/coursier/launchers/raw/master/cs-x86_64-pc-linux.gz | gzip -d > cs && chmod +x cs && ./cs setup +macOS-default: curl -fL https://github.com/coursier/launchers/raw/master/cs-x86_64-apple-darwin.gz | gzip -d > cs && chmod +x cs && (xattr -d com.apple.quarantine cs || true) && ./cs setup +macOS-brew: brew install coursier/formulas/coursier && cs setup +windows-link: https://github.com/coursier/launchers/raw/master/cs-x86_64-pc-win32.zip diff --git a/_includes/code-snippet.html b/_includes/code-snippet.html new file mode 100644 index 0000000000..0286da8b4d --- /dev/null +++ b/_includes/code-snippet.html @@ -0,0 +1,6 @@ +
+
+
+
+
{{include.codeSnippet}}
+
diff --git a/_includes/getting-started.md b/_includes/getting-started.md index 83c1de45fe..2df5661769 100644 --- a/_includes/getting-started.md +++ b/_includes/getting-started.md @@ -21,9 +21,29 @@ It ensures that a JVM and standard Scala tools are installed on your system. Install it on your system with the following instructions.
-
-

Follow the instructions to install the cs launcher then run:

-

$ ./cs setup

+
@@ -165,29 +185,3 @@ Once you've finished the above tutorials, consider checking out: ## Getting Help There are a multitude of mailing lists and real-time chat rooms in case you want to quickly connect with other Scala users. Check out our [community](https://scala-lang.org/community/) page for a list of these resources, and for where to reach out for help. - - - - - - - - - diff --git a/_includes/tabsection.html b/_includes/tabsection.html new file mode 100644 index 0000000000..a5473b04e5 --- /dev/null +++ b/_includes/tabsection.html @@ -0,0 +1,20 @@ +
+
+ {% for tabRoot in include.collection %} + + {% endfor %} +
+ {% for tabRoot in include.collection %} +
{{tabRoot.content}}
+ {% endfor %} +
diff --git a/_install_tabs/1-macos.md b/_install_tabs/1-macos.md new file mode 100644 index 0000000000..f91ab023fa --- /dev/null +++ b/_install_tabs/1-macos.md @@ -0,0 +1,23 @@ +--- +tabId: osx +tabLabel: macOS +--- +
+
+
+
+

Run the following command in your terminal, following the on-screen instructions:

+ {% include code-snippet.html language='bash' codeSnippet=site.data.setup-scala.macOS-brew %} +
+ +
+
+ {% include code-snippet.html language='bash' codeSnippet=site.data.setup-scala.macOS-default %} +
+
+
+
+
+
+
diff --git a/_install_tabs/2-linux.md b/_install_tabs/2-linux.md new file mode 100644 index 0000000000..6924edf275 --- /dev/null +++ b/_install_tabs/2-linux.md @@ -0,0 +1,14 @@ +--- +tabId: linux +tabLabel: Linux +--- +
+
+
+
+

Run the following command in your terminal, following the on-screen instructions:

+ {% include code-snippet.html language='bash' codeSnippet=site.data.setup-scala.linux %} +
+
+
+
diff --git a/_install_tabs/3-windows.md b/_install_tabs/3-windows.md new file mode 100644 index 0000000000..c3e31fb837 --- /dev/null +++ b/_install_tabs/3-windows.md @@ -0,0 +1,14 @@ +--- +tabId: windows +tabLabel: Windows +--- +
+
+
+
+

Download and execute the Scala + installer for Windows based on Coursier, and follow the on-screen instructions.

+
+
+
+
diff --git a/_install_tabs/4-other.md b/_install_tabs/4-other.md new file mode 100644 index 0000000000..d60085c17f --- /dev/null +++ b/_install_tabs/4-other.md @@ -0,0 +1,17 @@ +--- +tabId: other +tabLabel: Other +fallbackNoJS: true +--- +
+
+
+
+ +

Follow the documentation from Coursier on how to install and run cs setup.

+
+
+
+
diff --git a/_sass/layout/alt-details.scss b/_sass/layout/alt-details.scss new file mode 100644 index 0000000000..aae4addefb --- /dev/null +++ b/_sass/layout/alt-details.scss @@ -0,0 +1,46 @@ +// ALT-DETAILS +//------------------------------------------------ +//------------------------------------------------ + +.alt-details { + margin: 10px 0px; + + button.alt-details-toggle { + width: 100%; + border: none; + background-color: #b635c4; + padding: 5px 10px; + border-radius: 15px; + font-size: $font-size-medium; + cursor: pointer; + font-weight: 500; + color: #fff; + + &:hover { + background-color: #941fa1; + } + + &:after { + content: "\f13a"; // + font-family: "Font Awesome 5 Free"; + font-weight: 900; + font-size: 15px; + color: #fff; + float: right; + margin-top: 2px; + } + + &.alt-details-closed:after { + content: "\f138"; // + } + } + + .alt-details-detail { + background-color: rgb(248, 226, 255); + border: 1px solid rgb(239, 207, 248); + padding-top: 25px; + padding-bottom: 10px; + margin-top: -15px; + margin-bottom: 10px; + } +} diff --git a/_sass/layout/scala-in-action.scss b/_sass/layout/scala-in-action.scss new file mode 100755 index 0000000000..404c9bbd7f --- /dev/null +++ b/_sass/layout/scala-in-action.scss @@ -0,0 +1,158 @@ +// SCALA-IN-ACTION +//------------------------------------------------ +//------------------------------------------------ + +.scala-in-action { + + .tabcontent { + .scala-text { + .alt-details { + button.alt-details-toggle { + border: 1px solid #a0dff0; + background-color: #d1e5eb; + color: $gray; + + &:hover { + background-color: #c9e3eb; + } + + &:after { + color: $gray; + } + } + + .alt-details-detail { + background-color: $gray-light; + border: 1px solid darken($gray-light, 3%); + } + } + } + } + + .scala-in-action-content { + transition: $base-transition; + + + .scala-in-action-code { + // display: none; + // background: $gray-dark; + padding: 20px 0; + + .wrap { + margin-bottom: 0px; + } + + .snippet { + position: relative; + margin: 10px 0px; + cursor: default; + width: 100%; + + &:hover { + .buttons { + opacity: 0.95; + + &:active { + opacity: 0.3; + } + } + } + + .buttons { + position: absolute; + right: 4px; + top: 5px; + transition: all .2s ease; + display: flex; + opacity: 0; + flex-direction: row-reverse; + justify-content: flex-start; + + button { + outline: none; + background: #fff; + border: none; + font-size: $font-size-medium; + color: rgba($gray, .6); + cursor: pointer; + + i { + font-weight: $font-bold; + } + } + } + + pre.snippet-code { + margin: 0px; + display: block; + overflow-x: auto; + + code { + overflow-x: auto; + display: block; + } + } + } + + .scala-code { + + @include span-columns(7); + + @include bp(large) { + @include span-columns(12); + } + } + + .scala-text { + + details { + summary { + + &:hover { + background-color: lighten($gray-lighter, 5%); + } + } + + summary>* { + display: inline; + } + } + + code { + padding: 3px 6px; + color: #859900; + background-color: #fff; + border-radius: 10px; + border: 1px solid $gray-light; + } + + .snippet { + pre.snippet-code { + code { + border: 1px solid darken($gray-light, 10%); + } + } + } + + @include span-columns(5); + + @include bp(large) { + @include span-columns(12); + } + + h3 { + font-size: 1.525rem; + margin-bottom: 20px; + } + + p { + color: $base-font-color; + } + + &.scala-text-large { + @include span-columns(12); + } + } + } + } +} diff --git a/_sass/layout/tabsection.scss b/_sass/layout/tabsection.scss new file mode 100755 index 0000000000..71c2777183 --- /dev/null +++ b/_sass/layout/tabsection.scss @@ -0,0 +1,60 @@ +// TABSECTION +//------------------------------------------------ +//------------------------------------------------ + +.recommended-install { + margin-top: -2em; + .tabsection { + background: $gray-lighter; + } +} + +.tabsection { + + &.inline-tabs { + margin: 20px 0px; + } + + /* Style the tab */ + .tab { + overflow: hidden; + margin-bottom: -12px; + } + + /* Style the buttons that are used to open the tab content */ + .tab button { + font-family: $heading-font-family; + font-size: $font-size-medium; + font-weight: $font-bold; + color: lighten($gray, 25%); + background-color: inherit; + float: left; + border: none; + border-radius: 30px; + outline: none; + cursor: pointer; + padding: 14px 16px; + } + + /* Change background color of buttons on hover */ + .tab button:hover { + color: #fff; + background-color: $gray; + border-bottom: $base-border-white; + } + + /* Create an active/current tablink class */ + .tab button.active { + background-color: $gray; + border-bottom: $base-border-white; + color: #fff; + } + + /* Style the tab content */ + .tabcontent { + display: none; + padding: 0px 2px; + border-top: none; + transition: all .5s linear; + } +} diff --git a/resources/css/style.scss b/resources/css/style.scss index fb5c150296..02ed07ce47 100755 --- a/resources/css/style.scss +++ b/resources/css/style.scss @@ -28,6 +28,9 @@ @import 'layout/twitter-feed'; @import 'layout/cheatsheet'; @import 'layout/ides'; +@import 'layout/alt-details'; +@import 'layout/tabsection'; +@import 'layout/scala-in-action'; @import 'layout/nutshell'; @import 'layout/overviews'; @import 'layout/sips'; diff --git a/resources/js/functions.js b/resources/js/functions.js index e52eddd5cf..cd5ac73eac 100644 --- a/resources/js/functions.js +++ b/resources/js/functions.js @@ -404,6 +404,58 @@ $(document).ready(function() { } }); +const toggleElement = (evt, elemId) => { + const btn = evt.target; + const elem = document.getElementById(elemId); + if (elem.style.display === "none") { + elem.style.display = "block"; + } else { + elem.style.display = "none"; + } + $(btn).toggleClass("alt-details-closed"); +} + +$(document).ready(() => { + $('.alt-details-toggle').click(); +}); + +function copySnippet(evt) { + const snippet = evt.target.closest('.snippet').querySelector('.snippet-code'); + const code = snippet.querySelector('code').innerText; + window.navigator.clipboard.writeText(code) +} + +function openTab(evt, category, tabName) { + // Get all elements with class="tabcontent" and hide them + $('.tabcontent-' + category + '.tabcontent').css('display', 'none'); + + const queried = evt.target; + + // Get all elements with class="tablinks" and remove the class "active" + $('.tablinks-' + category + '.tablinks').removeClass('active'); + + // Show the current tab, and add an "active" class to the button that opened the tab + document.getElementById(category + '-' + tabName).style.display = "block"; + queried.className += " active"; +} + +$(document).ready(() => { + const defaultTabs = document.getElementsByClassName('default-tab'); + for (i = 0; i < defaultTabs.length; i++) { + defaultTabs[i].click(); + } +}); + +$(document).ready(function () { + if ($(".main-download").length) { + let os = getOS(); + if (os === 'unix') { + os = 'linux'; + } + $("#get-started-tab-" + os).click(); + } +}); + var image = { width: 1680, height: 1100 @@ -467,18 +519,18 @@ $('#filter-glossary-terms').focus(); //Footer scroll to top button -$(document).ready(function(){ - $(window).scroll(function(){ - if ($(this).scrollTop() > 100) { - $('#scroll-to-top-btn').fadeIn(); - } else { - $('#scroll-to-top-btn').fadeOut(); - } - }); - $('#scroll-to-top-btn').click(function(){ - $("html, body").animate({ scrollTop: 0 }, 600); - return false; - }); +$(document).ready(function(){ + $(window).scroll(function(){ + if ($(this).scrollTop() > 100) { + $('#scroll-to-top-btn').fadeIn(); + } else { + $('#scroll-to-top-btn').fadeOut(); + } + }); + $('#scroll-to-top-btn').click(function(){ + $("html, body").animate({ scrollTop: 0 }, 600); + return false; + }); }); //Contributors widget @@ -490,7 +542,7 @@ $(document).ready(function () { * - some files aren't prefixed with underscore, see rootFiles * - some files are placed in _overviews but rendered to its folder, see overviewsFolders */ - + let rootFiles = ['getting-started', 'learn', 'glossary']; let overviewsFolders = ['FAQ', 'cheatsheets', 'collections', 'compiler-options', 'core', 'jdk-compatibility', 'macros', 'parallel-collections', From 71cf7e946fc3377ab35ae90e46cf3a9a9d8bc531 Mon Sep 17 00:00:00 2001 From: Jamie Thompson Date: Fri, 29 Apr 2022 18:03:35 +0200 Subject: [PATCH 1848/3075] add tabs to other translated pages --- _fr/getting-started/index.md | 41 +++--------- _includes/_ja/getting-started.md | 39 +++--------- _includes/alt-details.html | 6 ++ _includes/code-snippet.html | 2 + _includes/getting-started.md | 45 +++++++------- _includes/tabsection.html | 4 ++ _install_tabs/1-macos.md | 20 +++--- _install_tabs/2-linux.md | 1 + _install_tabs/3-windows.md | 1 + _install_tabs/4-other.md | 1 + _install_tabs/fr-1-macos.md | 26 ++++++++ _install_tabs/fr-2-linux.md | 14 +++++ _install_tabs/fr-3-windows.md | 14 +++++ _install_tabs/fr-4-other.md | 19 ++++++ _install_tabs/ja-1-macos.md | 26 ++++++++ _install_tabs/ja-2-linux.md | 14 +++++ _install_tabs/ja-3-windows.md | 14 +++++ _install_tabs/ja-4-other.md | 18 ++++++ _layouts/downloadpage.html | 100 ------------------------------ _sass/layout/scala-in-action.scss | 3 +- resources/js/functions.js | 30 +++------ 21 files changed, 225 insertions(+), 213 deletions(-) create mode 100644 _includes/alt-details.html create mode 100644 _install_tabs/fr-1-macos.md create mode 100644 _install_tabs/fr-2-linux.md create mode 100644 _install_tabs/fr-3-windows.md create mode 100644 _install_tabs/fr-4-other.md create mode 100644 _install_tabs/ja-1-macos.md create mode 100644 _install_tabs/ja-2-linux.md create mode 100644 _install_tabs/ja-3-windows.md create mode 100644 _install_tabs/ja-4-other.md delete mode 100644 _layouts/downloadpage.html diff --git a/_fr/getting-started/index.md b/_fr/getting-started/index.md index f9b05d7df9..397c18e59c 100644 --- a/_fr/getting-started/index.md +++ b/_fr/getting-started/index.md @@ -24,13 +24,19 @@ Nous recommandons l'utilisation de l'outil d'installation "Coursier" qui va auto ### Utilisation de l'installateur Scala (recommandé) L'installateur Scala est un outil nommé [Coursier](https://get-coursier.io/docs/cli-overview), la commande principale de l'outil est `cs`. -Il s'assure que la JVM est les outils standards de Scala sont installés sur votre système. +Il s'assure que la JVM est les outils standards de Scala sont installés sur votre système. Installez-le sur votre système avec les instructions suivantes.
-
-

Suivez les instructions pour installer la commande cs puis exécutez :

-

$ ./cs setup

+
@@ -165,30 +171,3 @@ Une fois que vous avez terminé le tutoriel ce dessus, vous pouvez consulter : Il y a plusieurs listes de diffusion et canaux de discussions instantanés si vous souhaitez rencontrer rapidement d'autres utilisateurs de Scala. Allez faire un tour sur notre page [community](https://scala-lang.org/community/) pour consulter la liste des ces ressources et obtenir de l'aide. Traduction par Antoine Pointeau. - - - - - - - - - diff --git a/_includes/_ja/getting-started.md b/_includes/_ja/getting-started.md index 1df3b33933..f747ff92f7 100644 --- a/_includes/_ja/getting-started.md +++ b/_includes/_ja/getting-started.md @@ -18,13 +18,18 @@ Scala のインストーラーは[Coursier](https://get-coursier.io/docs/cli-ove 以下の手順でお使いのシステムにインストールしてください。
-
-

Follow the instructions to install the cs launcher then run:

-

$ ./cs setup

+
- `cs setup` は JVM の管理だけでなく、便利なコマンドラインツールもインストールします: - JDK (インストール済みでなければ) @@ -141,29 +146,3 @@ IDE の使用に慣れている場合は、IDE から_Main.scala_のコードを ### (日本語のみ追記) Scala について日本語で質問したい場合、Twitterでつぶやくと気づいた人が教えてくれます。 - - - - - - - - - diff --git a/_includes/alt-details.html b/_includes/alt-details.html new file mode 100644 index 0000000000..52e8d9cf67 --- /dev/null +++ b/_includes/alt-details.html @@ -0,0 +1,6 @@ +
+ +
+ {{include.detail}} +
+
diff --git a/_includes/code-snippet.html b/_includes/code-snippet.html index 0286da8b4d..6267a08ad3 100644 --- a/_includes/code-snippet.html +++ b/_includes/code-snippet.html @@ -1,6 +1,8 @@
+ {% unless include.nocopy %}
+ {% endunless %}
{{include.codeSnippet}}
diff --git a/_includes/getting-started.md b/_includes/getting-started.md index 2df5661769..45c42b166f 100644 --- a/_includes/getting-started.md +++ b/_includes/getting-started.md @@ -20,31 +20,32 @@ The Scala installer is a tool named [Coursier](https://get-coursier.io/docs/cli- It ensures that a JVM and standard Scala tools are installed on your system. Install it on your system with the following instructions. +{% capture scalaDemo %}$ scala -version +Scala code runner version {{site.scala-3-version}} -- Copyright 2002-2022, LAMP/EPFL{% endcapture %} +
-
From 113f485c10c9143d9a5f081974a87061903b5a0d Mon Sep 17 00:00:00 2001 From: Julien Richard-Foy Date: Tue, 6 Jul 2021 16:29:35 +0200 Subject: [PATCH 1550/3075] Copy https://dotty.epfl.ch/docs/reference into https://docs.scala-lang.org/scala3/reference Content was taken from commit 270bd8b0f5af338be73790082d774516a83a73b5 --- _config.yml | 9 +- _data/scala3-doc-nav-header.yml | 2 +- _includes/sidebar-toc-multipage-overview.html | 2 +- _ja/index.md | 2 +- _ja/scala3/contribute-to-docs.md | 2 +- _ja/scala3/index.md | 2 +- _ja/scala3/new-in-scala3.md | 2 +- _overviews/FAQ/index.md | 4 +- _overviews/scala3-book/ca-summary.md | 2 +- _overviews/scala3-book/scala-features.md | 4 +- _overviews/scala3-macros/other-resources.md | 2 +- _overviews/scala3-macros/tutorial/inline.md | 2 +- .../compatibility-classpath.md | 36 +- .../compatibility-metaprogramming.md | 2 +- .../incompat-contextual-abstractions.md | 2 +- .../incompat-dropped-features.md | 10 +- .../incompat-other-changes.md | 2 +- .../incompat-type-inference.md | 2 +- .../scala3-migration/incompatibility-table.md | 4 +- _overviews/scala3-reference/overview.md | 7 - _scala3-reference/changed-features.md | 9 + .../changed-features/compiler-plugins.md | 130 +++ .../changed-features/eta-expansion-spec.md | 77 ++ .../changed-features/eta-expansion.md | 44 + .../implicit-conversions-spec.md | 117 +++ .../changed-features/implicit-conversions.md | 66 ++ .../changed-features/implicit-resolution.md | 170 ++++ _scala3-reference/changed-features/imports.md | 61 ++ .../changed-features/interpolation-escapes.md | 14 + .../changed-features/lazy-vals-init.md | 82 ++ .../changed-features/main-functions.md | 91 ++ .../changed-features/match-syntax.md | 58 ++ .../changed-features/numeric-literals.md | 264 ++++++ .../changed-features/operators.md | 167 ++++ .../changed-features/overload-resolution.md | 94 ++ .../changed-features/pattern-bindings.md | 62 ++ .../changed-features/pattern-matching.md | 246 ++++++ .../changed-features/structural-types-spec.md | 153 ++++ .../changed-features/structural-types.md | 194 ++++ .../changed-features/type-checking.md | 9 + .../changed-features/type-inference.md | 12 + .../changed-features/vararg-splices.md | 42 + .../changed-features/wildcards.md | 52 ++ _scala3-reference/contextual.md | 85 ++ .../contextual/by-name-context-parameters.md | 67 ++ .../contextual/context-bounds.md | 48 + .../contextual/context-functions-spec.md | 79 ++ .../contextual/context-functions.md | 156 ++++ _scala3-reference/contextual/conversions.md | 78 ++ .../contextual/derivation-macro.md | 204 +++++ _scala3-reference/contextual/derivation.md | 405 +++++++++ .../contextual/extension-methods.md | 308 +++++++ _scala3-reference/contextual/given-imports.md | 119 +++ _scala3-reference/contextual/givens.md | 173 ++++ .../contextual/multiversal-equality.md | 229 +++++ .../contextual/relationship-implicits.md | 208 +++++ .../right-associative-extension-methods.md | 52 ++ _scala3-reference/contextual/type-classes.md | 284 ++++++ _scala3-reference/contextual/using-clauses.md | 155 ++++ _scala3-reference/dropped-features.md | 9 + .../dropped-features/auto-apply.md | 98 +++ .../dropped-features/class-shadowing-spec.md | 26 + .../dropped-features/class-shadowing.md | 35 + .../dropped-features/delayed-init.md | 32 + .../dropped-features/do-while.md | 43 + .../dropped-features/early-initializers.md | 18 + .../dropped-features/existential-types.md | 37 + _scala3-reference/dropped-features/limit22.md | 19 + _scala3-reference/dropped-features/macros.md | 18 + .../dropped-features/nonlocal-returns.md | 26 + .../dropped-features/package-objects.md | 49 ++ .../dropped-features/procedure-syntax.md | 21 + _scala3-reference/dropped-features/symlits.md | 12 + .../dropped-features/this-qualifier.md | 17 + .../dropped-features/type-projection.md | 20 + .../dropped-features/weak-conformance-spec.md | 54 ++ .../dropped-features/weak-conformance.md | 49 ++ .../dropped-features/wildcard-init.md | 25 + _scala3-reference/dropped-features/xml.md | 41 + _scala3-reference/enums.md | 9 + _scala3-reference/enums/adts.md | 175 ++++ _scala3-reference/enums/desugarEnums.md | 217 +++++ _scala3-reference/enums/enums.md | 196 +++++ _scala3-reference/experimental/canthrow.md | 242 +++++ .../experimental/erased-defs-spec.md | 65 ++ _scala3-reference/experimental/erased-defs.md | 229 +++++ _scala3-reference/features-classification.md | 201 +++++ .../language-versions.md | 2 +- _scala3-reference/metaprogramming.md | 49 ++ .../metaprogramming/compiletime-ops.md | 296 +++++++ _scala3-reference/metaprogramming/inline.md | 380 ++++++++ .../metaprogramming/macros-spec.md | 254 ++++++ _scala3-reference/metaprogramming/macros.md | 825 ++++++++++++++++++ .../metaprogramming/reflection.md | 133 +++ .../metaprogramming/simple-smp.md | 232 +++++ _scala3-reference/metaprogramming/staging.md | 123 +++ .../metaprogramming/tasty-inspect.md | 59 ++ _scala3-reference/new-types.md | 9 + .../dependent-function-types-spec.md | 125 +++ .../new-types/dependent-function-types.md | 51 ++ .../new-types/intersection-types-spec.md | 108 +++ .../new-types/intersection-types.md | 70 ++ _scala3-reference/new-types/match-types.md | 247 ++++++ .../new-types/polymorphic-function-types.md | 96 ++ .../new-types/type-lambdas-spec.md | 119 +++ _scala3-reference/new-types/type-lambdas.md | 19 + .../new-types/union-types-spec.md | 172 ++++ _scala3-reference/new-types/union-types.md | 48 + _scala3-reference/other-new-features.md | 9 + .../other-new-features/control-syntax.md | 49 ++ .../creator-applications.md | 59 ++ .../other-new-features/explicit-nulls.md | 540 ++++++++++++ .../other-new-features/export.md | 179 ++++ .../indentation-experimental.md | 83 ++ .../other-new-features/indentation.md | 455 ++++++++++ .../other-new-features/kind-polymorphism.md | 49 ++ .../other-new-features/matchable.md | 143 +++ .../other-new-features/named-typeargs-spec.md | 39 + .../other-new-features/named-typeargs.md | 33 + .../other-new-features/opaques-details.md | 123 +++ .../other-new-features/opaques.md | 169 ++++ .../other-new-features/open-classes.md | 82 ++ .../parameter-untupling-spec.md | 88 ++ .../other-new-features/parameter-untupling.md | 48 + .../other-new-features/safe-initialization.md | 246 ++++++ .../other-new-features/targetName.md | 122 +++ .../threadUnsafe-annotation.md | 20 + .../other-new-features/trait-parameters.md | 90 ++ .../other-new-features/transparent-traits.md | 72 ++ .../other-new-features/type-test.md | 183 ++++ _scala3-reference/overview.md | 155 ++++ _scala3-reference/soft-modifier.md | 27 + _scala3-reference/syntax.md | 445 ++++++++++ _zh-cn/index.md | 2 +- index.md | 2 +- .../explicit-nulls-type-hierarchy.png | Bin 0 -> 57752 bytes scala3/contribute-to-docs.md | 6 +- scala3/guides.md | 4 - scala3/index.md | 2 +- scala3/new-in-scala3.md | 2 +- 140 files changed, 13826 insertions(+), 64 deletions(-) delete mode 100644 _overviews/scala3-reference/overview.md create mode 100644 _scala3-reference/changed-features.md create mode 100644 _scala3-reference/changed-features/compiler-plugins.md create mode 100644 _scala3-reference/changed-features/eta-expansion-spec.md create mode 100644 _scala3-reference/changed-features/eta-expansion.md create mode 100644 _scala3-reference/changed-features/implicit-conversions-spec.md create mode 100644 _scala3-reference/changed-features/implicit-conversions.md create mode 100644 _scala3-reference/changed-features/implicit-resolution.md create mode 100644 _scala3-reference/changed-features/imports.md create mode 100644 _scala3-reference/changed-features/interpolation-escapes.md create mode 100644 _scala3-reference/changed-features/lazy-vals-init.md create mode 100644 _scala3-reference/changed-features/main-functions.md create mode 100644 _scala3-reference/changed-features/match-syntax.md create mode 100644 _scala3-reference/changed-features/numeric-literals.md create mode 100644 _scala3-reference/changed-features/operators.md create mode 100644 _scala3-reference/changed-features/overload-resolution.md create mode 100644 _scala3-reference/changed-features/pattern-bindings.md create mode 100644 _scala3-reference/changed-features/pattern-matching.md create mode 100644 _scala3-reference/changed-features/structural-types-spec.md create mode 100644 _scala3-reference/changed-features/structural-types.md create mode 100644 _scala3-reference/changed-features/type-checking.md create mode 100644 _scala3-reference/changed-features/type-inference.md create mode 100644 _scala3-reference/changed-features/vararg-splices.md create mode 100644 _scala3-reference/changed-features/wildcards.md create mode 100644 _scala3-reference/contextual.md create mode 100644 _scala3-reference/contextual/by-name-context-parameters.md create mode 100644 _scala3-reference/contextual/context-bounds.md create mode 100644 _scala3-reference/contextual/context-functions-spec.md create mode 100644 _scala3-reference/contextual/context-functions.md create mode 100644 _scala3-reference/contextual/conversions.md create mode 100644 _scala3-reference/contextual/derivation-macro.md create mode 100644 _scala3-reference/contextual/derivation.md create mode 100644 _scala3-reference/contextual/extension-methods.md create mode 100644 _scala3-reference/contextual/given-imports.md create mode 100644 _scala3-reference/contextual/givens.md create mode 100644 _scala3-reference/contextual/multiversal-equality.md create mode 100644 _scala3-reference/contextual/relationship-implicits.md create mode 100644 _scala3-reference/contextual/right-associative-extension-methods.md create mode 100644 _scala3-reference/contextual/type-classes.md create mode 100644 _scala3-reference/contextual/using-clauses.md create mode 100644 _scala3-reference/dropped-features.md create mode 100644 _scala3-reference/dropped-features/auto-apply.md create mode 100644 _scala3-reference/dropped-features/class-shadowing-spec.md create mode 100644 _scala3-reference/dropped-features/class-shadowing.md create mode 100644 _scala3-reference/dropped-features/delayed-init.md create mode 100644 _scala3-reference/dropped-features/do-while.md create mode 100644 _scala3-reference/dropped-features/early-initializers.md create mode 100644 _scala3-reference/dropped-features/existential-types.md create mode 100644 _scala3-reference/dropped-features/limit22.md create mode 100644 _scala3-reference/dropped-features/macros.md create mode 100644 _scala3-reference/dropped-features/nonlocal-returns.md create mode 100644 _scala3-reference/dropped-features/package-objects.md create mode 100644 _scala3-reference/dropped-features/procedure-syntax.md create mode 100644 _scala3-reference/dropped-features/symlits.md create mode 100644 _scala3-reference/dropped-features/this-qualifier.md create mode 100644 _scala3-reference/dropped-features/type-projection.md create mode 100644 _scala3-reference/dropped-features/weak-conformance-spec.md create mode 100644 _scala3-reference/dropped-features/weak-conformance.md create mode 100644 _scala3-reference/dropped-features/wildcard-init.md create mode 100644 _scala3-reference/dropped-features/xml.md create mode 100644 _scala3-reference/enums.md create mode 100644 _scala3-reference/enums/adts.md create mode 100644 _scala3-reference/enums/desugarEnums.md create mode 100644 _scala3-reference/enums/enums.md create mode 100644 _scala3-reference/experimental/canthrow.md create mode 100644 _scala3-reference/experimental/erased-defs-spec.md create mode 100644 _scala3-reference/experimental/erased-defs.md create mode 100644 _scala3-reference/features-classification.md rename {_overviews/scala3-reference => _scala3-reference}/language-versions.md (99%) create mode 100644 _scala3-reference/metaprogramming.md create mode 100644 _scala3-reference/metaprogramming/compiletime-ops.md create mode 100644 _scala3-reference/metaprogramming/inline.md create mode 100644 _scala3-reference/metaprogramming/macros-spec.md create mode 100644 _scala3-reference/metaprogramming/macros.md create mode 100644 _scala3-reference/metaprogramming/reflection.md create mode 100644 _scala3-reference/metaprogramming/simple-smp.md create mode 100644 _scala3-reference/metaprogramming/staging.md create mode 100644 _scala3-reference/metaprogramming/tasty-inspect.md create mode 100644 _scala3-reference/new-types.md create mode 100644 _scala3-reference/new-types/dependent-function-types-spec.md create mode 100644 _scala3-reference/new-types/dependent-function-types.md create mode 100644 _scala3-reference/new-types/intersection-types-spec.md create mode 100644 _scala3-reference/new-types/intersection-types.md create mode 100644 _scala3-reference/new-types/match-types.md create mode 100644 _scala3-reference/new-types/polymorphic-function-types.md create mode 100644 _scala3-reference/new-types/type-lambdas-spec.md create mode 100644 _scala3-reference/new-types/type-lambdas.md create mode 100644 _scala3-reference/new-types/union-types-spec.md create mode 100644 _scala3-reference/new-types/union-types.md create mode 100644 _scala3-reference/other-new-features.md create mode 100644 _scala3-reference/other-new-features/control-syntax.md create mode 100644 _scala3-reference/other-new-features/creator-applications.md create mode 100644 _scala3-reference/other-new-features/explicit-nulls.md create mode 100644 _scala3-reference/other-new-features/export.md create mode 100644 _scala3-reference/other-new-features/indentation-experimental.md create mode 100644 _scala3-reference/other-new-features/indentation.md create mode 100644 _scala3-reference/other-new-features/kind-polymorphism.md create mode 100644 _scala3-reference/other-new-features/matchable.md create mode 100644 _scala3-reference/other-new-features/named-typeargs-spec.md create mode 100644 _scala3-reference/other-new-features/named-typeargs.md create mode 100644 _scala3-reference/other-new-features/opaques-details.md create mode 100644 _scala3-reference/other-new-features/opaques.md create mode 100644 _scala3-reference/other-new-features/open-classes.md create mode 100644 _scala3-reference/other-new-features/parameter-untupling-spec.md create mode 100644 _scala3-reference/other-new-features/parameter-untupling.md create mode 100644 _scala3-reference/other-new-features/safe-initialization.md create mode 100644 _scala3-reference/other-new-features/targetName.md create mode 100644 _scala3-reference/other-new-features/threadUnsafe-annotation.md create mode 100644 _scala3-reference/other-new-features/trait-parameters.md create mode 100644 _scala3-reference/other-new-features/transparent-traits.md create mode 100644 _scala3-reference/other-new-features/type-test.md create mode 100644 _scala3-reference/overview.md create mode 100644 _scala3-reference/soft-modifier.md create mode 100644 _scala3-reference/syntax.md create mode 100644 resources/images/scala3/explicit-nulls/explicit-nulls-type-hierarchy.png diff --git a/_config.yml b/_config.yml index 395bed4a34..64f78bc718 100644 --- a/_config.yml +++ b/_config.yml @@ -45,6 +45,8 @@ collections: getting-started: output: true permalink: /:collection/:path.html + scala3-reference: # not really a collection, but this is the only way I found to be able to generate the navigation bar on the right + output: true ja: # Japanese translations output: true permalink: /:collection/:path.html @@ -125,13 +127,14 @@ defaults: permalink: "/scala3/guides/macros/:title.html" - scope: - path: "_overviews/scala3-reference" + path: "_scala3-reference" values: scala3: true partof: scala3-reference + type: section overview-name: "Scala 3 Language Reference" layout: multipage-overview - permalink: "/scala3/guides/reference/:title.html" + permalink: "/scala3/reference/:path.html" - scope: path: "scala3" @@ -142,7 +145,7 @@ defaults: highlighter: rouge permalink: /:categories/:title.html:output_ext baseurl: -scala3ref: "/scala3/guides/reference" +scala3ref: "/scala3/reference" exclude: ["vendor"] plugins: - jekyll-redirect-from diff --git a/_data/scala3-doc-nav-header.yml b/_data/scala3-doc-nav-header.yml index c390278c6d..94e3bfa5c5 100644 --- a/_data/scala3-doc-nav-header.yml +++ b/_data/scala3-doc-nav-header.yml @@ -12,6 +12,6 @@ - title: Migrate url: "/scala3/guides/migration/compatibility-intro.html" - title: Reference - url: "https://dotty.epfl.ch/docs/reference/overview.html" + url: "/scala3/reference/overview.html" - title: API url: "https://dotty.epfl.ch/api/index.html" diff --git a/_includes/sidebar-toc-multipage-overview.html b/_includes/sidebar-toc-multipage-overview.html index ceab98320f..168f4b5950 100644 --- a/_includes/sidebar-toc-multipage-overview.html +++ b/_includes/sidebar-toc-multipage-overview.html @@ -9,7 +9,7 @@
Contents
{% endif %}
-
-

Gitter

- Real-time (topic-specialized) chat +
+

Chat

+ Real-time chat on Discord
-
! Jekyll/Marulu limitation {% endcomment %} +

From f317bfc00ca5272eeaa6556cb395e3dae8e0f9cc Mon Sep 17 00:00:00 2001 From: Vojin Jovanovic Date: Fri, 19 Apr 2013 18:07:58 +0200 Subject: [PATCH 0018/3075] Bug reporting guide. --- contribute/bug-reporting-guide.md | 120 +++++++++++++++++------------- 1 file changed, 70 insertions(+), 50 deletions(-) diff --git a/contribute/bug-reporting-guide.md b/contribute/bug-reporting-guide.md index 345dc03034..9b89f60ef4 100644 --- a/contribute/bug-reporting-guide.md +++ b/contribute/bug-reporting-guide.md @@ -3,53 +3,73 @@ layout: page title: Bug Reporting --- -# Reporting bugs to the Scala project - -The Scala project tracker is located at: - -> [http://issues.scala-lang.org](http://issues.scala-lang.org) - - -{% comment %} -WHAT THIS PAGE SHOULD TALK ABOUT: - - tracker - - what's a bug and what's not a bug? - - is it in the scala area? - - library - - compiler - - reflection - - scaladoc - - external libraries have their own trackers: - - akka - - play - - lift - - slick - - if it's a compiler crasher, it's a bug - - if the code generated throws a VerifyError, it's a bug - - if it's a regression, i.e. it worked in the previous version, it's a bug - - if the code generated is not doing what you expected, then it may or may not be a bug - - minimize the problem - - decouple from libraries - - decouple from complex build systems - - it could be a separate compilation issue - does it happen if you clean everything before? - - create small and self-contained files that, when compiled, will exhibit the behavior - - even if the behavior is not what you hoped for, it might still be correct - - if possible, look at the Scala Reference Specification and SIP documents - - or ask on the scala-internals mailing list - - okay, I'm sure it's a bug, now what? - - search for similar bugs - - the exception name and phase should be the best keywords to search for - - if the bug is there, add your test case as a comment. When someone picks up the bug, they will have to add your test case as a confirmation test - - if there's no similar bug - - try to fill in as many fields as possible: - - scala version - - component (if you know) - - labels - - assigneee may be left empty, as all new bugs are triaged - - environment - Machine architecture, Operating system, Java virtual machine version, any other environment necessary - - description - - - the test case - - the commands to trigger the bug - - the expected output - - the actual output -{% endcomment %} +# Reporting Bugs to the Scala Project + +The Scala project tracker is located at [http://issues.scala-lang.org](http://issues.scala-lang.org). Before you submit a bug make sure that it is certainly a bug by following instructions in *Is it a Bug?*. + +## Is it a Bug? + +The first step in identifying a bug is to identify which component of the Scala distribution is affected. First, ensure that your issue falls within any of the following categories: + + - **Library** bugs typically manifest themselves as run-time exceptions, or as *unexpected*/*unintuitive* behavior of Scala Standard Library methods. + - **Compiler** errors are manifested as compile time exceptions, unexpected behavior of your code at run time, or invalid behavior of the type system. + - **Reflection** are bugs that appear in the ‘scala.reflect’ package. For the *reflection* bugs , the same rules apply as for the *library* bugs. + - **Scaladoc** bugs are manifested as a logical problems in the information it presents (that is, the displayed information is incorrect, such as an incorrect subclassing relationship), or incorrect behavior of the user interface. If you'd like to suggest a change in the content of the documentation, please submit a pull request (possible to do in the browser using GitHub, which is easier and faster than filing a bug). Please file a bug about the content of documentation only if you cannot provide a suggestion for its fix. + +If your issue is related to any of the following external libraries, make sure to use the relevant project's issue tracker: + + - [Akka](http://doc.akka.io/docs/akka/current/project/issue-tracking.html) + - [Play!](http://github.com/playframework/Play20/issues) + - [Slick](http://github.com/slick/slick/issues) + - [Actors Migration Kit](http://github.com/scala/actors-migration/issues?state=open) + +The following are generally considered to be bugs: + +- **Scala Compiler Crash** If the Scala compiler is crashing with an internal error (compile time exception) you have certainly found a bug, and can move on to the next section of this document on reporting confirmed bugs. +- **Regressions** If some code snippet worked in a previous Scala release, but now no longer compiles or results in an exception, it is probably a regression. +- **Verify Errors** happen when the compiled Scala program is loaded to the Java Virtual Machine. If you're getting a *Verify Error*, you've usually found a bug. Make sure first that your project is not using stale `.class` files before reporting a new issue. + +If you have a code snippet that is resulting in bytecode which you believe is behaving incorrectly, you may or may not have found a bug. Before reporting your issue, please attempt the following: + +* Make sure you minimize your problem. To correctly minimize the problem follow the following instructions: + + 1. Gradually take apart the offensive code snippet until you believe you have the simplest representation of your problem. + + 2. Ensure that you have decoupled your code snippet from any library that could be introducing the offensive behavior. One way to achieve this is to try to recompile the offensive code snippet in isolation, outside of the context of any complex build environment. + + 3. Make sure you are compiling your project from a clean slate. Your problem could be related to separate compilation, which is difficult to detect without a clean build with new `.class` files. + +* Keep in mind that the behavior you are witnessing could be intended. Good resources for verifying whether or not behavior is intended is either in the [Scala Improvement Proposal Documents](http://docs.scala-lang.org/sips/sip-list.html) or in the [Scala Language Specification](http://www.scala-lang.org/docu/files/ScalaReference.pdf). If in doubt, you may always ask on the [scala-internals mailing list](https://groups.google.com/forum/?fromgroups#!forum/scala-internals) + +In general, if you find yourself stuck on any of these steps, asking on one of following Scala mailing lists can be helpful: + + - For compiler bugs use the [scala-internals](https://groups.google.com/forum/?fromgroups#!forum/scala-internals) mailing list. + - For unexpected behavior use [scala-language](https://groups.google.com/forum/?fromgroups#!forum/scala-language), or [scala-user](https://groups.google.com/forum/?fromgroups#!forum/scala-user) mailing lists. + +## Reporting Confirmed Bugs is a Sin + +Before reporting your bug, make sure to check the issue tracker for other similar bugs. The exception name or a compiler phase are the best keywords to search for. If you are experiencing unexpected behavior search for method/class names where it happens. Your issue might already be reported, and a workaround might already be available for you take advantage of. If your issue *is* reported, be sure to add your test case as a comment. + +**Note:** reporting a bug that already exists creates an additional overhead for you, the Scala Team, and all people that search the issue database. To avoid this inconvenience make sure that you thoroughly search for an existing issue. + +If you cannot find your issue in the issue tracker, create a new bug. The details about creating a bug report are in the following section. + +## Creating a Bug Report + +Please make sure to fill in as many fields as possible. Make sure you've indicated the following: + + 1. **Exact Scala version** that you are using. For example, `2.10.1` or `0.11.0-RC`. If the bug happens in mulitple versions indicate all of them. + 2. **The component** that is affected by the bug. For example, the Standard Library, Scaladoc, etc. + 3. **Labels** related to your issue. For example, if you think your issue is related to the typechecker, and if you have successfully minimized your issue, label your bug as "typechecker" and "minimized" + 4. **Running environment**. Are you running on Linux? Windows? What JVM version are you using? + +In order for us to quickly triage the bug that you've found, it's important that the code snippet which produces the observed issue is as minimized as possible. For advice on minimizing your code snippet, please see the appropriate subsection of the above (Is it a Bug?). + +### Description + +In the description of your issue, be as detailed as you can. Bug reports which have the following information included are typically understood, triaged, and fixed very quickly: + + 1. Include a test case (minimized if possible) enabling us to reproduce the problematic behavior. + 2. The expected output. + 3. The actual output. + 4. If you have already looked into the issue provide interesting insights or proposals for fixing the issue. \ No newline at end of file From fe39e1214a9b70ac76f223bde9670f66187b5810 Mon Sep 17 00:00:00 2001 From: Manojo Date: Tue, 23 Apr 2013 11:40:46 +0200 Subject: [PATCH 0019/3075] contribute -> get-involved --- contribute/bug-reporting-guide.md | 75 ------- contribute/documentation.md | 29 --- contribute/hacker-guide.md | 337 ------------------------------ contribute/index.md | 172 --------------- contribute/partest-guide.md | 66 ------ contribute/scala-fame.md | 9 - 6 files changed, 688 deletions(-) delete mode 100644 contribute/bug-reporting-guide.md delete mode 100644 contribute/documentation.md delete mode 100644 contribute/hacker-guide.md delete mode 100644 contribute/index.md delete mode 100644 contribute/partest-guide.md delete mode 100644 contribute/scala-fame.md diff --git a/contribute/bug-reporting-guide.md b/contribute/bug-reporting-guide.md deleted file mode 100644 index 9b89f60ef4..0000000000 --- a/contribute/bug-reporting-guide.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -layout: page -title: Bug Reporting ---- - -# Reporting Bugs to the Scala Project - -The Scala project tracker is located at [http://issues.scala-lang.org](http://issues.scala-lang.org). Before you submit a bug make sure that it is certainly a bug by following instructions in *Is it a Bug?*. - -## Is it a Bug? - -The first step in identifying a bug is to identify which component of the Scala distribution is affected. First, ensure that your issue falls within any of the following categories: - - - **Library** bugs typically manifest themselves as run-time exceptions, or as *unexpected*/*unintuitive* behavior of Scala Standard Library methods. - - **Compiler** errors are manifested as compile time exceptions, unexpected behavior of your code at run time, or invalid behavior of the type system. - - **Reflection** are bugs that appear in the ‘scala.reflect’ package. For the *reflection* bugs , the same rules apply as for the *library* bugs. - - **Scaladoc** bugs are manifested as a logical problems in the information it presents (that is, the displayed information is incorrect, such as an incorrect subclassing relationship), or incorrect behavior of the user interface. If you'd like to suggest a change in the content of the documentation, please submit a pull request (possible to do in the browser using GitHub, which is easier and faster than filing a bug). Please file a bug about the content of documentation only if you cannot provide a suggestion for its fix. - -If your issue is related to any of the following external libraries, make sure to use the relevant project's issue tracker: - - - [Akka](http://doc.akka.io/docs/akka/current/project/issue-tracking.html) - - [Play!](http://github.com/playframework/Play20/issues) - - [Slick](http://github.com/slick/slick/issues) - - [Actors Migration Kit](http://github.com/scala/actors-migration/issues?state=open) - -The following are generally considered to be bugs: - -- **Scala Compiler Crash** If the Scala compiler is crashing with an internal error (compile time exception) you have certainly found a bug, and can move on to the next section of this document on reporting confirmed bugs. -- **Regressions** If some code snippet worked in a previous Scala release, but now no longer compiles or results in an exception, it is probably a regression. -- **Verify Errors** happen when the compiled Scala program is loaded to the Java Virtual Machine. If you're getting a *Verify Error*, you've usually found a bug. Make sure first that your project is not using stale `.class` files before reporting a new issue. - -If you have a code snippet that is resulting in bytecode which you believe is behaving incorrectly, you may or may not have found a bug. Before reporting your issue, please attempt the following: - -* Make sure you minimize your problem. To correctly minimize the problem follow the following instructions: - - 1. Gradually take apart the offensive code snippet until you believe you have the simplest representation of your problem. - - 2. Ensure that you have decoupled your code snippet from any library that could be introducing the offensive behavior. One way to achieve this is to try to recompile the offensive code snippet in isolation, outside of the context of any complex build environment. - - 3. Make sure you are compiling your project from a clean slate. Your problem could be related to separate compilation, which is difficult to detect without a clean build with new `.class` files. - -* Keep in mind that the behavior you are witnessing could be intended. Good resources for verifying whether or not behavior is intended is either in the [Scala Improvement Proposal Documents](http://docs.scala-lang.org/sips/sip-list.html) or in the [Scala Language Specification](http://www.scala-lang.org/docu/files/ScalaReference.pdf). If in doubt, you may always ask on the [scala-internals mailing list](https://groups.google.com/forum/?fromgroups#!forum/scala-internals) - -In general, if you find yourself stuck on any of these steps, asking on one of following Scala mailing lists can be helpful: - - - For compiler bugs use the [scala-internals](https://groups.google.com/forum/?fromgroups#!forum/scala-internals) mailing list. - - For unexpected behavior use [scala-language](https://groups.google.com/forum/?fromgroups#!forum/scala-language), or [scala-user](https://groups.google.com/forum/?fromgroups#!forum/scala-user) mailing lists. - -## Reporting Confirmed Bugs is a Sin - -Before reporting your bug, make sure to check the issue tracker for other similar bugs. The exception name or a compiler phase are the best keywords to search for. If you are experiencing unexpected behavior search for method/class names where it happens. Your issue might already be reported, and a workaround might already be available for you take advantage of. If your issue *is* reported, be sure to add your test case as a comment. - -**Note:** reporting a bug that already exists creates an additional overhead for you, the Scala Team, and all people that search the issue database. To avoid this inconvenience make sure that you thoroughly search for an existing issue. - -If you cannot find your issue in the issue tracker, create a new bug. The details about creating a bug report are in the following section. - -## Creating a Bug Report - -Please make sure to fill in as many fields as possible. Make sure you've indicated the following: - - 1. **Exact Scala version** that you are using. For example, `2.10.1` or `0.11.0-RC`. If the bug happens in mulitple versions indicate all of them. - 2. **The component** that is affected by the bug. For example, the Standard Library, Scaladoc, etc. - 3. **Labels** related to your issue. For example, if you think your issue is related to the typechecker, and if you have successfully minimized your issue, label your bug as "typechecker" and "minimized" - 4. **Running environment**. Are you running on Linux? Windows? What JVM version are you using? - -In order for us to quickly triage the bug that you've found, it's important that the code snippet which produces the observed issue is as minimized as possible. For advice on minimizing your code snippet, please see the appropriate subsection of the above (Is it a Bug?). - -### Description - -In the description of your issue, be as detailed as you can. Bug reports which have the following information included are typically understood, triaged, and fixed very quickly: - - 1. Include a test case (minimized if possible) enabling us to reproduce the problematic behavior. - 2. The expected output. - 3. The actual output. - 4. If you have already looked into the issue provide interesting insights or proposals for fixing the issue. \ No newline at end of file diff --git a/contribute/documentation.md b/contribute/documentation.md deleted file mode 100644 index 05b2455a5f..0000000000 --- a/contribute/documentation.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -layout: page -title: Documentation Contributions ---- -# Contributing documentation to the Scala project - -TODO - - diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md deleted file mode 100644 index bd7ac60e71..0000000000 --- a/contribute/hacker-guide.md +++ /dev/null @@ -1,337 +0,0 @@ ---- -layout: page -title: Scala hacker guide ---- - -**Eugene Burmako** - -This guide is intended to help you get from an idea of fixing a bug or implementing a new feature into a nightly Scala build, and, ultimately, to a production release of Scala incorporating your idea. - -This guide covers the entire process, from the conception of your idea or bugfix to the point where it is merged into Scala. Throughout, we will use a running example of an idea or bugfix one might wish to contribute. - -## The Running Example - -Let's say that you particularly enjoy the new string interpolation language feature introduced in Scala 2.10.0, and you use it quite heavily. - -Though, there's an annoying issue -which you occasionally stumble upon: the formatting string interpolator `f` [does not support](https://issues.scala-lang.org/browse/SI-6725) -new line tokens `%n`. - -One approach would be to go the mailing list, request that the bug be fixed, and then to wait indefinitely for the fix arrive. Another approach would be to instead patch Scala oneself, and to submit the fix to the Scala repository in hopes that it might make it into a subsequent release. - -**_Of note_**: There are several types of releases/builds. Nightly builds are produced every night at a fixed time. Minor releases happen once every few months. Major releases typically happen once per year. - -## 1. Connect - -Sometimes it's appealing to hack alone and not to have to interact with others out of fear, or out of comfort. However, in the context a big project such as Scala, -this might not be the very best idea. There are people in the Scala community who have spent years accumulating knowledge about Scala libraries and internals. They might provide -unique insights and, what's even better, direct assistance in their areas, so it is not only advantageous, but recommended to communicate with the community about your new patch. - -Typically bug fixes new features start out as an idea or an experiment posted on one of our mailing lists [our mailing lists]({{ site.baseurl }}/community/index.html#mailing_lists) to find out how people feel -about things you want to implement. People proficient is certain areas of Scala usually monitor mailing lists, so you'll often get some help -by simply posting a message. But the most efficient way to connect is to cc your message to one of the people responsible for maintaining the aspect of Scala which you wish to contribute to. - -This is the list of language features/libraries along with their maintainers's full names and github usernames: - -{% include maintainers.html %} - -Since Martin is the person who submitted the string interpolation Scala Improvement Proposal and implemented this language feature for Scala 2.10.0, he might be interested in learning of new bugfixes to that feature. - -As alluded to earlier, one must also choose an appropriate mailing list. Typically, one would use the scala-internals mailing list, as it is devoted to discussions about the core internal design and implementation of the Scala system. However, since this issue has been discussed previously on the scala-user mailing list, -in this example, we post to the [the scala-user mailing list](http://groups.google.com/group/scala-user)about our issue. - -
Posting to scala-user
-
-
Response from Martin
- -Now that we have the approval of the feature's author, we can get to work! - -## 2. Set up - -Hacking Scala begins with creating a branch for your work item. To develop Scala we use [Git](http://git-scm.com/) -and [GitHub](http://github.com/). This section of the guide provides a short walkthrough, but if you are new to Git, -it probably makes sense to familiarize yourself with Git first. We recommend the [Git Pro](http://git-scm.com/book/en/) -online book. - -### Fork - -Log into [GitHub](http://github.com/), go to [https://github.com/scala/scala](https://github.com/scala/scala) and click the `Fork` -button in the top right corner of the page. This will create your own copy of our repository that will serve as a scratchpad for your work. - -If you're new to Git, don't be afraid of messing up-- there is no way you can corrupt our repository. - -
Fork scala/scala
- -### Clone - -If everything went okay, you will be redirected to your own fork at `https://github.com/username/scala`, where `username` -is your github user name. You might find it helpful to read [http://help.github.com/fork-a-repo/](http://help.github.com/fork-a-repo/), -which covers some of the things that will follow below. Then, _clone_ your repository (_i.e._ pull a copy from github to your local machine) by running the following on the command line: - - 16:35 ~/Projects$ git clone https://github.com/xeno-by/scala - Cloning into 'scala'... - remote: Counting objects: 258564, done. - remote: Compressing objects: 100% (58239/58239), done. - remote: Total 258564 (delta 182155), reused 254094 (delta 178356) - Receiving objects: 100% (258564/258564), 46.91 MiB | 700 KiB/s, done. - Resolving deltas: 100% (182155/182155), done. - -This will create a local directory called `scala`, which contains a clone of your own copy of our repository. The changes that you make -in this directory can be propagated back to your copy hosted on github and, ultimately, pushed into Scala when your patch is ready. - -### Branch - -Before you start making changes, always create your own branch. Never work on the `master` branch. Think of a name that describes -the changes you plan on making. Use a prefix that describes the nature of your change. There are essentially two kinds of changes: -bug fixes and new features. - -* For bug fixes, use `issue/NNNN` for bug NNNN from the [Scala issue tracker](https://issues.scala-lang.org/). -* For new feature use `topic/XXX` for feature XXX. Use feature names that make sense in the context of the whole Scala project and not just to you personally. For example, if you work on diagrams in Scaladoc, use `topic/scaladoc-diagrams` instead of just `topic/diagrams` would be a good branch name. - -Since in our example, we're going to fix an existing bug [SI-6725](https://issues.scala-lang.org/browse/SI-6725), we'll create a branch named `ticket/6725`. - - 16:39 ~/Projects/scala (master)$ git checkout -b ticket/6725 - Switched to a new branch 'ticket/6725' - -If you are new to Git and branching, read the [Branching Chapter](http://git-scm.com/book/en/Git-Branching) in the Git Pro book. - -### Build - -The next step after cloning your fork is setting up your machine to build Scala. The definitive guide on building Scala is located at -[https://github.com/scala/scala/blob/master/README.rst](https://github.com/scala/scala/blob/master/README.rst), but here's the summary: - -* It is recommended to use Java `1.6` (not `1.7` or `1.8`, because they might cause occasional glitches). -* The build tool is `ant`. -* The build runs the `pull-binary-libs.sh` script to download bootstrap libs. This requires `bash` and `curl`. -* The majority of our team works on Linux and OS X, so these operating systems are guaranteed to work. -* Windows is supported, but it might have issues. Please report to [the issue tracker](https://issues.scala-lang.org/) if you encounter any. - -Building Scala is as easy as running `ant` in the root of your cloned repository. Be prepared to wait for a while-- a full "clean" build -takes 8+ minutes depending on your machine (and up to 30 minutes on older machines with less memory). Incremental builds are usually within 30-120 seconds range (again, your mileage might vary -with your hardware). - - 16:50 ~/Projects/scala (ticket/6725)$ ant - Buildfile: /Users/xeno_by/Projects/scala/build.xml - - strap.clean: - - pack.clean: - - init.jars.check: - - init.jars: - [echo] Updating bootstrap libs. (To do this by hand, run ./pull-binary-libs.sh) - [exec] Resolving [943cd5c8802b2a3a64a010efb86ec19bac142e40/lib/ant/ant-contrib.jar] - - ... - - pack.bin: - [mkdir] Created dir: /Users/xeno_by/Projects/scala/build/pack/bin - - pack.done: - - build: - - BUILD SUCCESSFUL - Total time: 9 minutes 41 seconds - -### IDE - -There's no single editor of choice for working with Scala sources, as there are trade-offs associated with each available tool. - -Both Eclipse and IntelliJ IDEA have Scala plugins, which are known to work with our codebase. Here are -[instructions for Eclipse](https://github.com/scala/scala/blob/master/src/eclipse/README.md) and -[instructions for Intellij](https://github.com/scala/scala/blob/master/src/intellij/README). Both of those Scala plugins provide -navigation, refactoring and error reporting functionality as well as integrated debugging. - -There also exist lighter-weight editors such as Emacs, Sublime or jEdit which provide unparalleled are faster and much less memory/compute-intensive to run, while -lacking semantic services and debugging. To address this shortcoming, they can integrate with ENSIME, -a helper program, which hosts a resident Scala compiler providing some of the features implemented in traditional IDEs. However despite -having significantly matured over the last year, support for our particular code base is still being improved, and is not as mature as for Eclipse and IntelliJ. - -Due to the immense variability in personal preference between IDE/editor experience, it's difficult to recommend a particular tool, and your choice should boil down to your personal preferences. - -## 3. Hack - -When hacking on your topic of choice, you'll be modifying Scala, compiling it and testing it on relevant input files. -Typically you would want to first make sure that your changes work on a small example and afterwards verify that nothing break -by running a comprehensive test suite. - -We'll start by creating a `sandbox` directory (this particular name doesn't bear any special meaning), which will hold a single test file and its compilation results. First, let's make sure that -[the bug](https://issues.scala-lang.org/browse/SI-6725) is indeed reproducible by putting together a simple test and compiling and running it with the Scala compiler that we built using `ant`. The Scala compiler that we just built is located in `build/pack/bin`. - - 17:25 ~/Projects/scala (ticket/6725)$ mkdir sandbox - 17:26 ~/Projects/scala (ticket/6725)$ cd sandbox - 17:26 ~/Projects/scala/sandbox (ticket/6725)$ edit Test.scala - 17:26 ~/Projects/scala/sandbox (ticket/6725)$ cat Test.scala - object Test extends App { - val a = 1 - val s = f"$a%s%n$a%s" - println(s) - } - 17:27 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scalac Test.scala - 17:28 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scala Test - 1%n1 // %n should've been replaced by a newline here - -### Implement - -Now, implement your bugfix or new feature! - -Here are also some tips & tricks that have proven useful in Scala development: - -* If after introducing changes or updating your clone, you get `AbstractMethodError` or other linkage exceptions, - try doing `ant clean build`. Due to the way how Scala compiles traits, if a trait changes, then it's sometimes not enough to recompile - just that trait, but it might also be necessary to recompile its users. The `ant` tool is not smart enough to do that, which might lead to - very strange errors. Full-rebuilds fix the problem. Fortunately that's rarely necessary, because full-rebuilds take a lot of time-- the same 8-30 minutes as mentioned above. -* Even on solid state drives packaging Scala distribution (i.e. creating jars from class files) is a non-trivial task. To save time here, - some people in our team do `ant quick.comp` instead of `ant` and then create custom scripts to launch Scala from `build/quick/classes`. -* Don't underestimate the power of `print`. When starting with Scala, I spent a lot of time in the debugger trying to figure out how - things work. However later I found out that print-based debugging is often more effective than jumping around. While it might be obvious - to some, I'd like to explicitly mention that it's also useful to print stack traces to understand the flow of execution. - -### Documentation - -There are several areas that one could contribute to-- there is the Scala library, the Scala compiler, and other tools such as Scaladoc. Each area has varying amounts of documentation. - -##### The Scala Library - -Contributing to the Scala standard library is about the same as working on one of your own libraries. Beyond the Scala collections hierarchy, there are no complex internals or architectures to have to worry about. Just make sure that you code in a "don't-repeat-yourself" (DRY) style, obeying the "boy scout principle" (i.e. make sure you've left something cleaner than you found it.) - -If documentation is necessary for some trait/class/object/method/etc in the Scala standard library, typically maintainers will include inline comments describing their design decisions or rationale for implementing things the way they have, if it is not straightforward. - -If you intend on contributing to Scala collections, please make sure you're familiar with the design of the Scala collections library. It can be easy to put an implementation in the wrong location if you are unfamiliar with the collections architecture. There is an excellent and very detailed guide covering [the Architecture of Scala Collections](http://docs.scala-lang.org/overviews/core/architecture-of-scala-collections.html), as well as a larger more general [Scala collections Guide](http://docs.scala-lang.org/overviews/core/collections.html) covering the sequential portion of collections. For parallel collections, there also exists a detailed [Scala Parallel Collections Guide](http://docs.scala-lang.org/overviews/core/parallel-collections.html). (TODO double check these links!) - -##### The Scala Compiler - -Documentation about the internal workings of the Scala compiler is scarce, and most of the knowledge is passed around by email (scala-internals mailing list), ticket, or word of mouth. However the situation is steadily improving. Here are the resources that might help: - -* [Compiler internals videos by Martin Odersky](TODO) are quite dated, but still very useful. In this three-video - series Martin explains the general architecture of the compiler, and the basics of the front-end, which has recently become Scala reflection API. -* [Reflection documentation](http://docs.scala-lang.org/overviews/reflection/overview.html) describes fundamental data structures (like `Tree`s, `Symbol`s, and `Types`) that - are used to represent Scala programs and operations defined on then. Since much of the compiler has been factored out and made accessible via the Reflection API, all of the fundamentals needed for reflection are the same for the compiler. -* [Reflection and Compilers by Martin Odersky](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Reflection-and-Compilers), a talk - at Lang.NEXT 2012 in which Martin elaborates on the design of scalac and the architecture of the reflection API. -* [Scala compiler corner](http://lampwww.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/) contains extensive documentation about - most of the post-typer phases (i.e. the backend) in the Scala compiler. -* [scala-internals](http://groups.google.com/group/scala-internals), a mailing list which hosts discussions about the core - internal design and implementation of the Scala system. - -##### Other Projects - -Tools like Scaladoc also welcome contributions. Unfortunately these smaller projects have less developer documentation. In these cases, the best thing to do is to directly explore the code base (which often contains documentation as inline comments) or to write to the appropriate maintainers for pointers. - -### Interlude - -To fix [the bug we're interested in](https://issues.scala-lang.org/browse/SI-6725). Let's say we've tracked the `StringContext.f` interpolator -down to a macro implemented in `MacroImplementations.scala`, and there we notice that the interpolator only processes conversions, -but not tokens like `%n`. Looks like an easy fix. - - 18:44 ~/Projects/scala/sandbox (ticket/6725)$ git diff - diff --git a/src/compiler/scala/tools/reflect/MacroImplementations.scala b/src/compiler/scala/tools/ - index 002a3fce82..4e8f02084d 100644 - --- a/src/compiler/scala/tools/reflect/MacroImplementations.scala - +++ b/src/compiler/scala/tools/reflect/MacroImplementations.scala - @@ -117,7 +117,8 @@ abstract class MacroImplementations { - if (!strIsEmpty) { - val len = str.length - while (idx < len) { - - if (str(idx) == '%') { - + def notPercentN = str(idx) != '%' || (idx + 1 < len && str(idx + 1) != 'n') - + if (str(idx) == '%' && notPercentN) { - bldr append (str substring (start, idx)) append "%%" - start = idx + 1 - } - -After applying the fix and running `ant`, our simple test case in `sandbox/Test.scala` started working! - - 18:51 ~/Projects/scala/sandbox (ticket/6725)$ cd .. - 18:51 ~/Projects/scala (ticket/6725)$ ant - Buildfile: /Users/xeno_by/Projects/scala/build.xml - - ... - - quick.comp: - [scalacfork] Compiling 1 file to /Users/xeno_by/Projects/scala/build/quick/classes/compiler - [propertyfile] Updating property file: /Users/xeno_by/Projects/scala/build/quick/classes/compiler/compiler.properties - [stopwatch] [quick.comp.timer: 6.588 sec] - - ... - - BUILD SUCCESSFUL - Total time: 18 seconds - - 18:51 ~/Projects/scala (ticket/6725)$ cd sandbox - 18:51 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scalac Test.scala - 18:51 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scala Test - 1 - 1 // no longer getting the %n here - it got transformed into a newline - -### Verify - -Now to make sure that my fix doesn't break anything I need to run the test suite using the `partest` tool we wrote to test Scala. -Read up [the partest guide](/contribute/partest-guide.html) to learn the details about partest, but in a nutshell you can either -run `ant test` to go through the entire test suite (30+ minutes) or use wildcards to limit the tests to something manageable: - - 18:52 ~/Projects/scala/sandbox (ticket/6725)$ cd ../test - 18:56 ~/Projects/scala/test (ticket/6725)$ partest files/run/*interpol* - Testing individual files - testing: [...]/files/run/interpolationArgs.scala [ OK ] - testing: [...]/files/run/interpolationMultiline1.scala [ OK ] - testing: [...]/files/run/interpolationMultiline2.scala [ OK ] - testing: [...]/files/run/sm-interpolator.scala [ OK ] - testing: [...]/files/run/interpolation.scala [ OK ] - testing: [...]/files/run/stringinterpolation_macro-run.scala [ OK ] - All of 6 tests were successful (elapsed time: 00:00:08) - -## 4. Publish - -After development is finished, it's time to publish the code and submit your patch for discussion and potential inclusion into Scala. -In a nutshell, this involves: - - 1. making sure that your code and commit messages are of high quality, - 2. clicking a few buttons in the Github interface, - 3. assigning one or more reviewers which will look through your pull request. - - Let's go into each of these points in more detail. - -### Commit - -The [Git Basics](http://git-scm.com/book/en/Git-Basics) chapter in the Git online book covers most of the basic workflow during this stage. -There are two things you should know here: - - 1. Commit messages are often the only way to understand the intentions of authors of code written a few years ago. Thus, writing a quality is of utmost importance. The more context you provide for the change you've introduced, the larger the chance that some future maintainer understand your intentions. Consult [the pull request policy](https://github.com/scala/scala/wiki/Pull-Request-Policy) for more information about the desired style of your commits. - - 2. Keeping Scala's git history clean is also important. Therefore we won't accept pull requests for bug fixes that have more than one commit. For features, it is okay to have several commits, but all tests need to pass after every single commit. To clean up your commit structure, you want to [rewrite history](http://git-scm.com/book/en/Git-Branching-Rebasing) using `git rebase` so that your commits are against the latest revision of `master`. - -Once you are satisfied with your work, synced with `master` and cleaned up your commits you are ready to submit a patch to the central Scala repository. Before proceeding make sure you have pushed all of your local changes to your fork on Github. - - 19:22 ~/Projects/scala/test (ticket/6725)$ git add ../src/compiler/scala/tools/reflect/MacroImplementations.scala - 19:22 ~/Projects/scala/test (ticket/6725)$ git commit - [ticket/6725 3c3098693b] SI-6725 `f` interpolator now supports %n tokens - 1 file changed, 2 insertions(+), 1 deletion(-) - 19:34 ~/Projects/scala/test (ticket/6725)$ git push origin ticket/6725 - Username for 'https://github.com': xeno-by - Password for 'https://xeno-by@github.com': - Counting objects: 15, done. - Delta compression using up to 8 threads. - Compressing objects: 100% (8/8), done. - Writing objects: 100% (8/8), 1.00 KiB, done. - Total 8 (delta 5), reused 0 (delta 0) - To https://github.com/xeno-by/scala - * [new branch] ticket/6725 -> ticket/6725 - -### Submit - -Now, we must simply submit our proposed patch. Navigate to your branch in Github (for me it was `https://github.com/xeno-by/scala/tree/ticket/6725`) -and click the pull request button to submit your patch as a pull request to Scala. If you've never submitted patches to Scala, you will -need to sign the contributor license agreement, which [can be done online](http://typesafe.com/contribute/cla/scala) within a few minutes. - -
Submit a pull request
- -### Discuss - -After the pull request has been submitted, you need to pick a reviewer (usually the person you've contacted in the beginning of your -workflow) and be ready to elaborate and adjust your patch if necessary. In this example, we picked Martin, because we had such a nice chat on the mailing list: - -
SAssign the reviewer
- diff --git a/contribute/index.md b/contribute/index.md deleted file mode 100644 index 05696f5165..0000000000 --- a/contribute/index.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -layout: page -title: Contribute ---- -# Contributing to the Scala project - -The Scala programming langauge is an open source project with a very -diverse community, where people from all over the world contribute their work, -with everyone benefitting from friendly help and advice, and -kindly helping others in return. So why not join the Scala community and help -everyone make things better? - -The following are typical questions you might ask when first contributing to Scala. -If you have other questions not addressed here, feel free to ask on the [scala-internals mailing list](http://groups.google.com/group/scala-internals). - -
- -### I found something that doesn't work as expected. How to file a bug report? - -[The reporting bugs page](bug-reporting-guide.html) describes the steps to take when you find something that doesn't work -as expected. Filing in a good bug report increases the chances the ticket is fixed quickly. - -
- -### Why contribute a patch to Scala? - -Just to name a few common reasons: - - contributing a patch is the best way to make sure your desired changes will be available in the next Scala version - - Scala is written in Scala, so going through the source code and patching it will improve your Scala-fu - - last but not least, you will make it into the [Scala Contribuitor Hall of Fame](scala-fame.html). - -
- -### I'd like to start hacking the Scala project, how to find something to work on? - -Depending on your skillset, you may want to contribute documentation and/or code. Documentation has always been very -appreciated work in the Scala community, as most code contributions tend to be quite scarce in explanations of how -things work and how everyone else is supposed to use them. To contribute documentation, have a look at the -[documentation page](documentation.html). - -The main Scala project consists of the standard Scala library, the Scala reflection and macros library, -the Scala compiler and the Scaladoc tool. This means there's plenty to choose from when deciding what to work on. -Typically the scaladoc tool provides a low entry point for new committers, so it is a good first step into contributing. - -On the Scala bug tracker you will find many bugs that are [marked as good starting points to contributing ("community" bugs)](https://issues.scala-lang.org/secure/IssueNavigator.jspa?requestId=12111) or [that are not currently assigned](https://issues.scala-lang.org/secure/IssueNavigator.jspa?requestId=12112) and that you could pick up. Once you decided on a ticket to look at, see the next step on how to proceed further. - -{% comment %} Keep the space in the
! Jekyll/Marulu limitation {% endcomment %} -
- -
- -### I have this idea that I'd like to add to Scala, how do I start? - -The first step to making a change is to discuss it with the community at large, to make sure everyone agrees on the idea -and on the implementation plan. Starting point ("community") bugs are usually uncontroversial, so you can jump right -ahead to hacking the scala source tree and filing a pull request. For larger changes it is best to announce the change -on the [scala-internals](http://groups.google.com/group/scala-internals) mailing list and get developer feedback. For really complex changes, a [Scala Improvement Process (SIP)](http://docs.scala-lang.org/sips/) document might be required, but the first step is always to discuss it on the mailing list. - -Contributions, big or small, simple or complex, controversial or undisputed, need to materialize as patches against -the Scala project source tree. The [hacker guide](hacker-guide.html) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. - -
- - \ No newline at end of file diff --git a/contribute/partest-guide.md b/contribute/partest-guide.md deleted file mode 100644 index e681c569fe..0000000000 --- a/contribute/partest-guide.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -layout: page -title: Running the Test Suite ---- - -Partest is a custom parallel testing tool that we use to run the test suite for the Scala compiler and library. Go the scala project folder from your local checkout and run it via `ant` or standalone as follows. - -## Using ant - -The test suite can be run by using ant from the command line: - - $ ant test.suite - -## Standalone - -There are launch scripts `partest` and `partest.bat` in the `test` folder of the scala project. To have partest run failing tests only and print details about test failures to the console, you can use - - ./test/partest --show-diff --show-log --failed - -You can get a summary of the usage by running partest without arguments. - -* Most commonly you want to invoke partest with an option that tells it which part of the tests to run. For example `--all`, `--pos`, `--neg` or `--run`. -* You can test individual files by specifying individual test files (`.scala` files) as options. Several files can be tested if they are from the same category, e.g., `pos`. -* You can enable output of log and diff using the `-show-log` and `-show-diff` options. -* If you get into real trouble, and want to find out what partest does, you can run it with option `--verbose`. This info is useful as part of bug reports. -* Set custom path from where to load classes: `-classpath ` and `-buildpath `. -* You can use the `SCALAC_OPTS` environment variable to pass command line options to the compiler. -* You can use the `JAVA_OPTS` environment variable to pass command line options to the runner (e.g., for `run/jvm` tests). -* The launch scripts run partest as follows: - - scala -cp scala.tools.partest.nest.NestRunner - - Partest classes from a `quick` build, e.g., can be found in `./build/quick/classes/partest/`. - - Partest will tell you where it loads compiler/library classes from by adding the `partest.debug` property: - - scala -Dpartest.debug=true -cp scala.tools.partest.nest.NestRunner - - - -## ScalaCheck tests - -Tests that depend on [ScalaCheck](https://github.com/rickynils/scalacheck) can be added under folder `./test/files/scalacheck`. A sample test: - - import org.scalacheck._ - import Prop._ - - object Test { - val prop_ConcatLists = property{ (l1: ListInt, l2: ListInt) => - l1.size + l2.size == (l1 ::: l2).size - } - - val tests = List(("prop_ConcatLists", prop_ConcatLists)) - } - -## Troubleshooting - -### Windows - -Some tests might fail because line endings in the `.check` files and the produced results do not match. In that case, set either - - git config core.autocrlf false - -or - - git config core.autocrlf input \ No newline at end of file diff --git a/contribute/scala-fame.md b/contribute/scala-fame.md deleted file mode 100644 index 75317be820..0000000000 --- a/contribute/scala-fame.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -layout: page -title: Scala Contribuitor Hall of Fame ---- -# Scala Hall of Fame - -A big thank you to everyone who contributed to: - - [the Scala library and compiler](https://github.com/scala/scala/contributors) - - [the Scala documentation website](https://github.com/scala/scala.github.com/contributors) \ No newline at end of file From ab597ab0b5dde3577da92ef3fd803f6e00675b94 Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Thu, 30 May 2013 13:25:09 +0100 Subject: [PATCH 0020/3075] Going back to having a 'Contribute' section --- contribute/bug-reporting-guide.md | 89 +++++ contribute/documentation.md | 29 ++ contribute/hacker-guide.md | 337 ++++++++++++++++++ contribute/index.md | 201 +++++++++++ contribute/partest-guide.md | 66 ++++ .../_posts/2013-03-01-scala-fame-2013-02.md | 182 ++++++++++ .../_posts/2013-04-01-scala-fame-2013-03.md | 126 +++++++ .../_posts/2013-05-01-scala-fame-2013-04.md | 91 +++++ contribute/scala-fame.md | 14 + 9 files changed, 1135 insertions(+) create mode 100644 contribute/bug-reporting-guide.md create mode 100644 contribute/documentation.md create mode 100644 contribute/hacker-guide.md create mode 100644 contribute/index.md create mode 100644 contribute/partest-guide.md create mode 100644 contribute/scala-fame-data/_posts/2013-03-01-scala-fame-2013-02.md create mode 100644 contribute/scala-fame-data/_posts/2013-04-01-scala-fame-2013-03.md create mode 100644 contribute/scala-fame-data/_posts/2013-05-01-scala-fame-2013-04.md create mode 100644 contribute/scala-fame.md diff --git a/contribute/bug-reporting-guide.md b/contribute/bug-reporting-guide.md new file mode 100644 index 0000000000..e286ce2002 --- /dev/null +++ b/contribute/bug-reporting-guide.md @@ -0,0 +1,89 @@ +--- +layout: page +title: Bug Reporting +--- + +# Reporting Bugs to the Scala Project + +The Scala project tracker is located at [http://issues.scala-lang.org](http://issues.scala-lang.org). Before you submit a bug make sure that it is certainly a bug by following instructions in *Is it a Bug?*. + +## Is it a Bug? + +The first step in identifying a bug is to identify which component of the Scala distribution is affected. First, ensure that your issue falls within any of the following categories: + + - **Library** bugs typically manifest themselves as run-time exceptions, or as *unexpected*/*unintuitive* behavior of Scala Standard Library methods. + - **Compiler** errors are manifested as compile time exceptions, unexpected behavior of your code at run time, or invalid behavior of the type system. + - **Reflection** are bugs that appear in the ‘scala.reflect’ package. For the *reflection* bugs , the same rules apply as for the *library* bugs. + - **Scaladoc** bugs are manifested as a logical problems in the information it presents (that is, the displayed information is incorrect, such as an incorrect subclassing relationship), or incorrect behavior of the user interface. If you'd like to suggest a change in the content of the documentation, please submit a pull request (possible to do in the browser using GitHub, which is easier and faster than filing a bug). Please file a bug about the content of documentation only if you cannot provide a suggestion for its fix. + +If your issue is related to any of the following external projects, make sure to use its appropriate issue tracker: + + - [Akka](http://doc.akka.io/docs/akka/current/project/issue-tracking.html) + - [Play!](http://github.com/playframework/Play20/issues) + - [Slick](http://github.com/slick/slick/issues) + - [Actors Migration Kit](http://github.com/scala/actors-migration/issues?state=open) + - [Scala IDE](https://scala-ide-portfolio.assembla.com/spaces/scala-ide/support/tickets) + - [sbt](https://github.com/sbt/sbt/issues) + +The following are generally considered to be bugs: + +- **Scala Compiler Crash** If the Scala compiler is crashing with an internal error (compile time exception) you have certainly found a bug, and can move on to the next section of this document on reporting confirmed bugs. +- **Regressions** If some code snippet worked in a previous Scala release, but now no longer compiles or results in an exception, it is probably a regression. +- **Verify Errors** happen when the compiled Scala program is loaded to the Java Virtual Machine. If you're getting a *Verify Error*, you've usually found a bug. Make sure first that your project is not using stale `.class` files before reporting a new issue. + +If you have a code snippet that is resulting in bytecode which you believe is behaving incorrectly, you may or may not have found a bug. Before reporting your issue, please attempt the following: + +* Make sure you minimize your problem. To correctly minimize the problem follow the following instructions: + + 1. Gradually take apart the offensive code snippet until you believe you have the simplest representation of your problem. + + 2. Ensure that you have decoupled your code snippet from any library that could be introducing the offensive behavior. One way to achieve this is to try to recompile the offensive code snippet in isolation, outside of the context of any complex build environment. If your code depends on some strictly Java library and source code is available for it, make sure that the latter is also minimized. + + 3. Make sure you are compiling your project from a clean slate. Your problem could be related to separate compilation, which is difficult to detect without a clean build with new `.class` files. + + 4. If you have encountered a bug while building your code in the IDE, then please reproduce it on the command line. The same rule applies for build tools like `sbt` or `ant`. + + 5. If you want to file an improvement in the issue tracker please discuss it first on one of the mailing lists. They offer much bigger audience than issue tracker. The latter is not suitable for long discussions. + +* Keep in mind that the behavior you are witnessing could be intended. Good formal resources for verifying whether or not the language behavior is intended is either in the [Scala Improvement Proposal Documents](http://docs.scala-lang.org/sips/sip-list.html) or in the [Scala Language Specification](http://www.scala-lang.org/docu/files/ScalaReference.pdf). If in doubt, you may always ask on the [scala-internals mailing list](https://groups.google.com/forum/?fromgroups#!forum/scala-internals) or [stackoveflow](http://stackoverflow.com/questions/tagged/scala). + +In general, if you find yourself stuck on any of these steps, asking on one of following Scala mailing lists can be helpful: + + - For unexpected behavior use [scala-language](https://groups.google.com/forum/?fromgroups#!forum/scala-language), or [scala-user](https://groups.google.com/forum/?fromgroups#!forum/scala-user) mailing lists. + - For compiler bugs use the [scala-internals](https://groups.google.com/forum/?fromgroups#!forum/scala-internals) mailing list. + +* Examples of exceptions reported by the compiler which usually are not bugs: + 1. `StackOverflowError` is typically not a bug unless the stacktrace involves the internal packages of the compiler (like `scala.tools.nsc...`). Try to increase the Java stack size (`-Xss`), in most of the cases it helps. + 2. `AbstractMethodError` can occur when you did not recompile all the necessary Scala files (build tools, like `sbt`, can prevent that from happening) or you are mixing external libraries compiled for different Scala versions (for example one uses `2.10.x` and the other `2.11.x`). + +## Reporting Confirmed Bugs is a Sin + +Before reporting your bug, make sure to check the issue tracker for other similar bugs. The exception name or a compiler phase are the best keywords to search for. If you are experiencing unexpected behavior search for method/class names where it happens. Your issue might already be reported, and a workaround might already be available for you take advantage of. If your issue *is* reported, be sure to add your test case as a comment if it is different from any of the existing ones. + +**Note:** reporting a bug that already exists creates an additional overhead for you, the Scala Team, and all people that search the issue database. To avoid this inconvenience make sure that you thoroughly search for an existing issue. + +If you cannot find your issue in the issue tracker, create a new bug. The details about creating a bug report are in the following section. + +## Creating a Bug Report + +Please make sure to fill in as many fields as possible. Make sure you've indicated the following: + + 1. **Exact Scala version** that you are using. For example, `2.10.1` or `2.11.0-RC`. If the bug happens in multiple versions indicate all of them. + 2. **The component** that is affected by the bug. For example, the Standard Library, Scaladoc, etc. + 3. **Labels** related to your issue. For example, if you think your issue is related to the typechecker, and if you have successfully minimized your issue, label your bug as "typechecker" and "minimized". Issue tracker will suggest names for existing labels as you type them so try not to create duplicates. + 4. **Running environment**. Are you running on Linux? Windows? What JVM version are you using? + +In order for us to quickly triage the bug that you've found, it's important that the code snippet which produces the observed issue is as minimized as possible. For advice on minimizing your code snippet, please see the appropriate subsection of the above (Is it a Bug?). + +### Description + +In the description of your issue, be as detailed as you can. Bug reports which have the following information included are typically understood, triaged, and fixed very quickly: + + 1. Include a test case (minimized if possible) enabling us to reproduce the problematic behavior. Include your test case (and output) in proper formatting `{code}` blocks: + + {code}Here you put your classes{code} + + 2. The expected output. + 3. The actual output, including the stacktrace. + 4. Related discussion on the mailing lists, if applicable. + 4. If you have already looked into the issue provide interesting insights or proposals for fixing the issue. \ No newline at end of file diff --git a/contribute/documentation.md b/contribute/documentation.md new file mode 100644 index 0000000000..05b2455a5f --- /dev/null +++ b/contribute/documentation.md @@ -0,0 +1,29 @@ +--- +layout: page +title: Documentation Contributions +--- +# Contributing documentation to the Scala project + +TODO + + diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md new file mode 100644 index 0000000000..758bb17115 --- /dev/null +++ b/contribute/hacker-guide.md @@ -0,0 +1,337 @@ +--- +layout: page +title: Scala hacker guide +--- + +**Eugene Burmako** + +This guide is intended to help you get from an idea of fixing a bug or implementing a new feature into a nightly Scala build, and, ultimately, to a production release of Scala incorporating your idea. + +This guide covers the entire process, from the conception of your idea or bugfix to the point where it is merged into Scala. Throughout, we will use a running example of an idea or bugfix one might wish to contribute. + +## The Running Example + +Let's say that you particularly enjoy the new string interpolation language feature introduced in Scala 2.10.0, and you use it quite heavily. + +Though, there's an annoying issue +which you occasionally stumble upon: the formatting string interpolator `f` [does not support](https://issues.scala-lang.org/browse/SI-6725) +new line tokens `%n`. + +One approach would be to go the mailing list, request that the bug be fixed, and then to wait indefinitely for the fix arrive. Another approach would be to instead patch Scala oneself, and to submit the fix to the Scala repository in hopes that it might make it into a subsequent release. + +**_Of note_**: There are several types of releases/builds. Nightly builds are produced every night at a fixed time. Minor releases happen once every few months. Major releases typically happen once per year. + +## 1. Connect + +Sometimes it's appealing to hack alone and not to have to interact with others out of fear, or out of comfort. However, in the context a big project such as Scala, +this might not be the very best idea. There are people in the Scala community who have spent years accumulating knowledge about Scala libraries and internals. They might provide +unique insights and, what's even better, direct assistance in their areas, so it is not only advantageous, but recommended to communicate with the community about your new patch. + +Typically bug fixes new features start out as an idea or an experiment posted on one of our mailing lists [our mailing lists]({{ site.baseurl }}/community/index.html#mailing_lists) to find out how people feel +about things you want to implement. People proficient is certain areas of Scala usually monitor mailing lists, so you'll often get some help +by simply posting a message. But the most efficient way to connect is to cc your message to one of the people responsible for maintaining the aspect of Scala which you wish to contribute to. + +This is the list of language features/libraries along with their maintainers's full names and github usernames: + +{% include maintainers.html %} + +Since Martin is the person who submitted the string interpolation Scala Improvement Proposal and implemented this language feature for Scala 2.10.0, he might be interested in learning of new bugfixes to that feature. + +As alluded to earlier, one must also choose an appropriate mailing list. Typically, one would use the scala-internals mailing list, as it is devoted to discussions about the core internal design and implementation of the Scala system. However, since this issue has been discussed previously on the scala-user mailing list, +in this example, we post to the [the scala-user mailing list](http://groups.google.com/group/scala-user)about our issue. + +
Posting to scala-user
+
+
Response from Martin
+ +Now that we have the approval of the feature's author, we can get to work! + +## 2. Set up + +Hacking Scala begins with creating a branch for your work item. To develop Scala we use [Git](http://git-scm.com/) +and [GitHub](http://github.com/). This section of the guide provides a short walkthrough, but if you are new to Git, +it probably makes sense to familiarize yourself with Git first. We recommend the [Git Pro](http://git-scm.com/book/en/) +online book. + +### Fork + +Log into [GitHub](http://github.com/), go to [https://github.com/scala/scala](https://github.com/scala/scala) and click the `Fork` +button in the top right corner of the page. This will create your own copy of our repository that will serve as a scratchpad for your work. + +If you're new to Git, don't be afraid of messing up-- there is no way you can corrupt our repository. + +
Fork scala/scala
+ +### Clone + +If everything went okay, you will be redirected to your own fork at `https://github.com/username/scala`, where `username` +is your github user name. You might find it helpful to read [http://help.github.com/fork-a-repo/](http://help.github.com/fork-a-repo/), +which covers some of the things that will follow below. Then, _clone_ your repository (_i.e._ pull a copy from github to your local machine) by running the following on the command line: + + 16:35 ~/Projects$ git clone https://github.com/xeno-by/scala + Cloning into 'scala'... + remote: Counting objects: 258564, done. + remote: Compressing objects: 100% (58239/58239), done. + remote: Total 258564 (delta 182155), reused 254094 (delta 178356) + Receiving objects: 100% (258564/258564), 46.91 MiB | 700 KiB/s, done. + Resolving deltas: 100% (182155/182155), done. + +This will create a local directory called `scala`, which contains a clone of your own copy of our repository. The changes that you make +in this directory can be propagated back to your copy hosted on github and, ultimately, pushed into Scala when your patch is ready. + +### Branch + +Before you start making changes, always create your own branch. Never work on the `master` branch. Think of a name that describes +the changes you plan on making. Use a prefix that describes the nature of your change. There are essentially two kinds of changes: +bug fixes and new features. + +* For bug fixes, use `issue/NNNN` for bug NNNN from the [Scala issue tracker](https://issues.scala-lang.org/). +* For new feature use `topic/XXX` for feature XXX. Use feature names that make sense in the context of the whole Scala project and not just to you personally. For example, if you work on diagrams in Scaladoc, use `topic/scaladoc-diagrams` instead of just `topic/diagrams` would be a good branch name. + +Since in our example, we're going to fix an existing bug [SI-6725](https://issues.scala-lang.org/browse/SI-6725), we'll create a branch named `ticket/6725`. + + 16:39 ~/Projects/scala (master)$ git checkout -b ticket/6725 + Switched to a new branch 'ticket/6725' + +If you are new to Git and branching, read the [Branching Chapter](http://git-scm.com/book/en/Git-Branching) in the Git Pro book. + +### Build + +The next step after cloning your fork is setting up your machine to build Scala. The definitive guide on building Scala is located at +[https://github.com/scala/scala/blob/master/README.rst](https://github.com/scala/scala/blob/master/README.rst), but here's the summary: + +* It is recommended to use Java `1.6` (not `1.7` or `1.8`, because they might cause occasional glitches). +* The build tool is `ant`. +* The build runs the `pull-binary-libs.sh` script to download bootstrap libs. This requires `bash` and `curl`. +* The majority of our team works on Linux and OS X, so these operating systems are guaranteed to work. +* Windows is supported, but it might have issues. Please report to [the issue tracker](https://issues.scala-lang.org/) if you encounter any. + +Building Scala is as easy as running `ant` in the root of your cloned repository. Be prepared to wait for a while-- a full "clean" build +takes 8+ minutes depending on your machine (and up to 30 minutes on older machines with less memory). Incremental builds are usually within 30-120 seconds range (again, your mileage might vary +with your hardware). + + 16:50 ~/Projects/scala (ticket/6725)$ ant + Buildfile: /Users/xeno_by/Projects/scala/build.xml + + strap.clean: + + pack.clean: + + init.jars.check: + + init.jars: + [echo] Updating bootstrap libs. (To do this by hand, run ./pull-binary-libs.sh) + [exec] Resolving [943cd5c8802b2a3a64a010efb86ec19bac142e40/lib/ant/ant-contrib.jar] + + ... + + pack.bin: + [mkdir] Created dir: /Users/xeno_by/Projects/scala/build/pack/bin + + pack.done: + + build: + + BUILD SUCCESSFUL + Total time: 9 minutes 41 seconds + +### IDE + +There's no single editor of choice for working with Scala sources, as there are trade-offs associated with each available tool. + +Both Eclipse and IntelliJ IDEA have Scala plugins, which are known to work with our codebase. Here are +[instructions for Eclipse](https://github.com/scala/scala/blob/master/src/eclipse/README.md) and +[instructions for Intellij](https://github.com/scala/scala/blob/master/src/intellij/README). Both of those Scala plugins provide +navigation, refactoring and error reporting functionality as well as integrated debugging. + +There also exist lighter-weight editors such as Emacs, Sublime or jEdit which provide unparalleled are faster and much less memory/compute-intensive to run, while +lacking semantic services and debugging. To address this shortcoming, they can integrate with ENSIME, +a helper program, which hosts a resident Scala compiler providing some of the features implemented in traditional IDEs. However despite +having significantly matured over the last year, support for our particular code base is still being improved, and is not as mature as for Eclipse and IntelliJ. + +Due to the immense variability in personal preference between IDE/editor experience, it's difficult to recommend a particular tool, and your choice should boil down to your personal preferences. + +## 3. Hack + +When hacking on your topic of choice, you'll be modifying Scala, compiling it and testing it on relevant input files. +Typically you would want to first make sure that your changes work on a small example and afterwards verify that nothing break +by running a comprehensive test suite. + +We'll start by creating a `sandbox` directory (this particular name doesn't bear any special meaning), which will hold a single test file and its compilation results. First, let's make sure that +[the bug](https://issues.scala-lang.org/browse/SI-6725) is indeed reproducible by putting together a simple test and compiling and running it with the Scala compiler that we built using `ant`. The Scala compiler that we just built is located in `build/pack/bin`. + + 17:25 ~/Projects/scala (ticket/6725)$ mkdir sandbox + 17:26 ~/Projects/scala (ticket/6725)$ cd sandbox + 17:26 ~/Projects/scala/sandbox (ticket/6725)$ edit Test.scala + 17:26 ~/Projects/scala/sandbox (ticket/6725)$ cat Test.scala + object Test extends App { + val a = 1 + val s = f"$a%s%n$a%s" + println(s) + } + 17:27 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scalac Test.scala + 17:28 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scala Test + 1%n1 // %n should've been replaced by a newline here + +### Implement + +Now, implement your bugfix or new feature! + +Here are also some tips & tricks that have proven useful in Scala development: + +* If after introducing changes or updating your clone, you get `AbstractMethodError` or other linkage exceptions, + try doing `ant clean build`. Due to the way how Scala compiles traits, if a trait changes, then it's sometimes not enough to recompile + just that trait, but it might also be necessary to recompile its users. The `ant` tool is not smart enough to do that, which might lead to + very strange errors. Full-rebuilds fix the problem. Fortunately that's rarely necessary, because full-rebuilds take a lot of time-- the same 8-30 minutes as mentioned above. +* Even on solid state drives packaging Scala distribution (i.e. creating jars from class files) is a non-trivial task. To save time here, + some people in our team do `ant quick.comp` instead of `ant` and then create custom scripts to launch Scala from `build/quick/classes`. +* Don't underestimate the power of `print`. When starting with Scala, I spent a lot of time in the debugger trying to figure out how + things work. However later I found out that print-based debugging is often more effective than jumping around. While it might be obvious + to some, I'd like to explicitly mention that it's also useful to print stack traces to understand the flow of execution. + +### Documentation + +There are several areas that one could contribute to-- there is the Scala library, the Scala compiler, and other tools such as Scaladoc. Each area has varying amounts of documentation. + +##### The Scala Library + +Contributing to the Scala standard library is about the same as working on one of your own libraries. Beyond the Scala collections hierarchy, there are no complex internals or architectures to have to worry about. Just make sure that you code in a "don't-repeat-yourself" (DRY) style, obeying the "boy scout principle" (i.e. make sure you've left something cleaner than you found it.) + +If documentation is necessary for some trait/class/object/method/etc in the Scala standard library, typically maintainers will include inline comments describing their design decisions or rationale for implementing things the way they have, if it is not straightforward. + +If you intend on contributing to Scala collections, please make sure you're familiar with the design of the Scala collections library. It can be easy to put an implementation in the wrong location if you are unfamiliar with the collections architecture. There is an excellent and very detailed guide covering [the Architecture of Scala Collections](http://docs.scala-lang.org/overviews/core/architecture-of-scala-collections.html), as well as a larger more general [Scala collections Guide](http://docs.scala-lang.org/overviews/core/collections.html) covering the sequential portion of collections. For parallel collections, there also exists a detailed [Scala Parallel Collections Guide](http://docs.scala-lang.org/overviews/core/parallel-collections.html). (TODO double check these links!) + +##### The Scala Compiler + +Documentation about the internal workings of the Scala compiler is scarce, and most of the knowledge is passed around by email (scala-internals mailing list), ticket, or word of mouth. However the situation is steadily improving. Here are the resources that might help: + +* [Compiler internals videos by Martin Odersky](TODO) are quite dated, but still very useful. In this three-video + series Martin explains the general architecture of the compiler, and the basics of the front-end, which has recently become Scala reflection API. +* [Reflection documentation](http://docs.scala-lang.org/overviews/reflection/overview.html) describes fundamental data structures (like `Tree`s, `Symbol`s, and `Types`) that + are used to represent Scala programs and operations defined on then. Since much of the compiler has been factored out and made accessible via the Reflection API, all of the fundamentals needed for reflection are the same for the compiler. +* [Reflection and Compilers by Martin Odersky](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2012/Reflection-and-Compilers), a talk + at Lang.NEXT 2012 in which Martin elaborates on the design of scalac and the architecture of the reflection API. +* [Scala compiler corner](http://lampwww.epfl.ch/~magarcia/ScalaCompilerCornerReloaded/) contains extensive documentation about + most of the post-typer phases (i.e. the backend) in the Scala compiler. +* [scala-internals](http://groups.google.com/group/scala-internals), a mailing list which hosts discussions about the core + internal design and implementation of the Scala system. + +##### Other Projects + +Tools like Scaladoc also welcome contributions. Unfortunately these smaller projects have less developer documentation. In these cases, the best thing to do is to directly explore the code base (which often contains documentation as inline comments) or to write to the appropriate maintainers for pointers. + +### Interlude + +To fix [the bug we're interested in](https://issues.scala-lang.org/browse/SI-6725). Let's say we've tracked the `StringContext.f` interpolator +down to a macro implemented in `MacroImplementations.scala`, and there we notice that the interpolator only processes conversions, +but not tokens like `%n`. Looks like an easy fix. + + 18:44 ~/Projects/scala/sandbox (ticket/6725)$ git diff + diff --git a/src/compiler/scala/tools/reflect/MacroImplementations.scala b/src/compiler/scala/tools/ + index 002a3fce82..4e8f02084d 100644 + --- a/src/compiler/scala/tools/reflect/MacroImplementations.scala + +++ b/src/compiler/scala/tools/reflect/MacroImplementations.scala + @@ -117,7 +117,8 @@ abstract class MacroImplementations { + if (!strIsEmpty) { + val len = str.length + while (idx < len) { + - if (str(idx) == '%') { + + def notPercentN = str(idx) != '%' || (idx + 1 < len && str(idx + 1) != 'n') + + if (str(idx) == '%' && notPercentN) { + bldr append (str substring (start, idx)) append "%%" + start = idx + 1 + } + +After applying the fix and running `ant`, our simple test case in `sandbox/Test.scala` started working! + + 18:51 ~/Projects/scala/sandbox (ticket/6725)$ cd .. + 18:51 ~/Projects/scala (ticket/6725)$ ant + Buildfile: /Users/xeno_by/Projects/scala/build.xml + + ... + + quick.comp: + [scalacfork] Compiling 1 file to /Users/xeno_by/Projects/scala/build/quick/classes/compiler + [propertyfile] Updating property file: /Users/xeno_by/Projects/scala/build/quick/classes/compiler/compiler.properties + [stopwatch] [quick.comp.timer: 6.588 sec] + + ... + + BUILD SUCCESSFUL + Total time: 18 seconds + + 18:51 ~/Projects/scala (ticket/6725)$ cd sandbox + 18:51 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scalac Test.scala + 18:51 ~/Projects/scala/sandbox (ticket/6725)$ ../build/pack/bin/scala Test + 1 + 1 // no longer getting the %n here - it got transformed into a newline + +### Verify + +Now to make sure that my fix doesn't break anything I need to run the test suite using the `partest` tool we wrote to test Scala. +Read up [the partest guide](partest-guide.html) to learn the details about partest, but in a nutshell you can either +run `ant test` to go through the entire test suite (30+ minutes) or use wildcards to limit the tests to something manageable: + + 18:52 ~/Projects/scala/sandbox (ticket/6725)$ cd ../test + 18:56 ~/Projects/scala/test (ticket/6725)$ partest files/run/*interpol* + Testing individual files + testing: [...]/files/run/interpolationArgs.scala [ OK ] + testing: [...]/files/run/interpolationMultiline1.scala [ OK ] + testing: [...]/files/run/interpolationMultiline2.scala [ OK ] + testing: [...]/files/run/sm-interpolator.scala [ OK ] + testing: [...]/files/run/interpolation.scala [ OK ] + testing: [...]/files/run/stringinterpolation_macro-run.scala [ OK ] + All of 6 tests were successful (elapsed time: 00:00:08) + +## 4. Publish + +After development is finished, it's time to publish the code and submit your patch for discussion and potential inclusion into Scala. +In a nutshell, this involves: + + 1. making sure that your code and commit messages are of high quality, + 2. clicking a few buttons in the Github interface, + 3. assigning one or more reviewers which will look through your pull request. + + Let's go into each of these points in more detail. + +### Commit + +The [Git Basics](http://git-scm.com/book/en/Git-Basics) chapter in the Git online book covers most of the basic workflow during this stage. +There are two things you should know here: + + 1. Commit messages are often the only way to understand the intentions of authors of code written a few years ago. Thus, writing a quality is of utmost importance. The more context you provide for the change you've introduced, the larger the chance that some future maintainer understand your intentions. Consult [the pull request policy](https://github.com/scala/scala/wiki/Pull-Request-Policy) for more information about the desired style of your commits. + + 2. Keeping Scala's git history clean is also important. Therefore we won't accept pull requests for bug fixes that have more than one commit. For features, it is okay to have several commits, but all tests need to pass after every single commit. To clean up your commit structure, you want to [rewrite history](http://git-scm.com/book/en/Git-Branching-Rebasing) using `git rebase` so that your commits are against the latest revision of `master`. + +Once you are satisfied with your work, synced with `master` and cleaned up your commits you are ready to submit a patch to the central Scala repository. Before proceeding make sure you have pushed all of your local changes to your fork on Github. + + 19:22 ~/Projects/scala/test (ticket/6725)$ git add ../src/compiler/scala/tools/reflect/MacroImplementations.scala + 19:22 ~/Projects/scala/test (ticket/6725)$ git commit + [ticket/6725 3c3098693b] SI-6725 `f` interpolator now supports %n tokens + 1 file changed, 2 insertions(+), 1 deletion(-) + 19:34 ~/Projects/scala/test (ticket/6725)$ git push origin ticket/6725 + Username for 'https://github.com': xeno-by + Password for 'https://xeno-by@github.com': + Counting objects: 15, done. + Delta compression using up to 8 threads. + Compressing objects: 100% (8/8), done. + Writing objects: 100% (8/8), 1.00 KiB, done. + Total 8 (delta 5), reused 0 (delta 0) + To https://github.com/xeno-by/scala + * [new branch] ticket/6725 -> ticket/6725 + +### Submit + +Now, we must simply submit our proposed patch. Navigate to your branch in Github (for me it was `https://github.com/xeno-by/scala/tree/ticket/6725`) +and click the pull request button to submit your patch as a pull request to Scala. If you've never submitted patches to Scala, you will +need to sign the contributor license agreement, which [can be done online](http://typesafe.com/contribute/cla/scala) within a few minutes. + +
Submit a pull request
+ +### Discuss + +After the pull request has been submitted, you need to pick a reviewer (usually the person you've contacted in the beginning of your +workflow) and be ready to elaborate and adjust your patch if necessary. In this example, we picked Martin, because we had such a nice chat on the mailing list: + +
SAssign the reviewer
+ diff --git a/contribute/index.md b/contribute/index.md new file mode 100644 index 0000000000..c3be3be994 --- /dev/null +++ b/contribute/index.md @@ -0,0 +1,201 @@ +--- +layout: page +title: Get Involved +--- +# Contributing to the Scala project + +The Scala programming language is an open source project with a very +diverse community, where people from all over the world contribute their work, +with everyone benefitting from friendly help and advice, and +kindly helping others in return. So why not join the Scala community and help +everyone make things better? + +
+
+
+

Scala Internals

+

Get a peek into the inners of the Scala compiler.

+
+
+

Report an issue

+

File a bug report or a feature request.

+
+
+

Documentation

+

Improve the documentation itself.

+
+
+ +
+
+

Write a SIP

+

Write a proposal for extending/improving Scala.

+
+
+

Hacker's guide

+

Learn to write good code and improve your chances of contributing to the Scala galaxy.

+
+
+

Community issues

+

Get cracking on some easy to approach issues.

+
+
+ +
+
+

Unassigned issues

+

Get serious with some more complex issues.

+
+
+

Hall of Fame

+

Track your rockstar status in the community.

+
+
+

Test your contributions

+

Learn how to run the Scala test suite.

+
+
+
+ + + +### Why contribute a patch to Scala? + +Just to name a few common reasons: + - contributing a patch is the best way to make sure your desired changes will be available in the next Scala version + - Scala is written in Scala, so going through the source code and patching it will improve your Scala-fu + - last but not least, you will make it into the [Scala Contributor Hall of Fame](scala-fame.html). + +
+ +The main Scala project consists of the standard Scala library, the Scala reflection and macros library, +the Scala compiler and the Scaladoc tool. This means there's plenty to choose from when deciding what to work on. +Typically the scaladoc tool provides a low entry point for new committers, so it is a good first step into contributing. + +On the Scala bug tracker you will find many bugs that are [marked as good starting points to contributing ("community" bugs)](https://issues.scala-lang.org/secure/IssueNavigator.jspa?requestId=12111) or [that are not currently assigned](https://issues.scala-lang.org/secure/IssueNavigator.jspa?requestId=12112) and that you could pick up. Once you decided on a ticket to look at, see the next step on how to proceed further. + +If you are interested in contributing code, we ask you to sign the +[Scala Contributor License Agreement](http://typesafe.com/contribute/cla/scala), +which allows us to ensure that all code submitted to the project is +unencumbered by copyrights or patents. + +
+ +### I have this idea that I'd like to add to Scala, how do I start? + +The first step to making a change is to discuss it with the community at large, to make sure everyone agrees on the idea +and on the implementation plan. Starting point ("community") bugs are usually uncontroversial, so you can jump right +ahead to hacking the scala source tree and filing a pull request. For larger changes it is best to announce the change +on the [scala-internals](http://groups.google.com/group/scala-internals) mailing list and get developer feedback. For really complex changes, a [Scala Improvement Process (SIP)](http://docs.scala-lang.org/sips/) document might be required, but the first step is always to discuss it on the mailing list. + +Contributions, big or small, simple or complex, controversial or undisputed, need to materialize as patches against +the Scala project source tree. The [hacker guide](hacker-guide.html) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. + +
+ + diff --git a/contribute/partest-guide.md b/contribute/partest-guide.md new file mode 100644 index 0000000000..e681c569fe --- /dev/null +++ b/contribute/partest-guide.md @@ -0,0 +1,66 @@ +--- +layout: page +title: Running the Test Suite +--- + +Partest is a custom parallel testing tool that we use to run the test suite for the Scala compiler and library. Go the scala project folder from your local checkout and run it via `ant` or standalone as follows. + +## Using ant + +The test suite can be run by using ant from the command line: + + $ ant test.suite + +## Standalone + +There are launch scripts `partest` and `partest.bat` in the `test` folder of the scala project. To have partest run failing tests only and print details about test failures to the console, you can use + + ./test/partest --show-diff --show-log --failed + +You can get a summary of the usage by running partest without arguments. + +* Most commonly you want to invoke partest with an option that tells it which part of the tests to run. For example `--all`, `--pos`, `--neg` or `--run`. +* You can test individual files by specifying individual test files (`.scala` files) as options. Several files can be tested if they are from the same category, e.g., `pos`. +* You can enable output of log and diff using the `-show-log` and `-show-diff` options. +* If you get into real trouble, and want to find out what partest does, you can run it with option `--verbose`. This info is useful as part of bug reports. +* Set custom path from where to load classes: `-classpath ` and `-buildpath `. +* You can use the `SCALAC_OPTS` environment variable to pass command line options to the compiler. +* You can use the `JAVA_OPTS` environment variable to pass command line options to the runner (e.g., for `run/jvm` tests). +* The launch scripts run partest as follows: + + scala -cp scala.tools.partest.nest.NestRunner + + Partest classes from a `quick` build, e.g., can be found in `./build/quick/classes/partest/`. + + Partest will tell you where it loads compiler/library classes from by adding the `partest.debug` property: + + scala -Dpartest.debug=true -cp scala.tools.partest.nest.NestRunner + + + +## ScalaCheck tests + +Tests that depend on [ScalaCheck](https://github.com/rickynils/scalacheck) can be added under folder `./test/files/scalacheck`. A sample test: + + import org.scalacheck._ + import Prop._ + + object Test { + val prop_ConcatLists = property{ (l1: ListInt, l2: ListInt) => + l1.size + l2.size == (l1 ::: l2).size + } + + val tests = List(("prop_ConcatLists", prop_ConcatLists)) + } + +## Troubleshooting + +### Windows + +Some tests might fail because line endings in the `.check` files and the produced results do not match. In that case, set either + + git config core.autocrlf false + +or + + git config core.autocrlf input \ No newline at end of file diff --git a/contribute/scala-fame-data/_posts/2013-03-01-scala-fame-2013-02.md b/contribute/scala-fame-data/_posts/2013-03-01-scala-fame-2013-02.md new file mode 100644 index 0000000000..fbdccb279c --- /dev/null +++ b/contribute/scala-fame-data/_posts/2013-03-01-scala-fame-2013-02.md @@ -0,0 +1,182 @@ +--- +layout: famearchive +title: Contributors of February 2013 +fame-year: 2013 +fame-month: 2 +fame-month-str: February +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://secure.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 38 + linesAdded: 2578 + linesDeleted: 2114 + rank: 1 + newContributor: false + - username: adriaanm + gravatar: https://secure.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 31 + linesAdded: 7110 + linesDeleted: 9889 + rank: 2 + newContributor: false + - username: JamesIry + gravatar: https://secure.gravatar.com/avatar/72b1a6b08fd8bb3068bd281974461c3e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 23 + linesAdded: 1673 + linesDeleted: 740 + rank: 3 + newContributor: false + - username: paulp + gravatar: https://secure.gravatar.com/avatar/c25d674f69bb9c155f265a7482712be4?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 10 + linesAdded: 1466 + linesDeleted: 1097 + rank: 4 + newContributor: false + - username: gkossakowski + gravatar: https://secure.gravatar.com/avatar/e608c8cb27858cc5aaf7d0c1e57958d7?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 2 + linesAdded: 4 + linesDeleted: 1 + rank: 5 + newContributor: false + - category: EPFL + authors: + - username: xeno-by + gravatar: https://secure.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 29 + linesAdded: 2108 + linesDeleted: 724 + rank: 1 + newContributor: false + - username: lrytz + gravatar: https://secure.gravatar.com/avatar/d807dd5133a6fc14c821178e53c34091?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 3 + linesAdded: 213 + linesDeleted: 31 + rank: 2 + newContributor: false + - username: heathermiller + gravatar: https://secure.gravatar.com/avatar/54d0b6494927c0040b96ed327202e8dc?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 2 + linesAdded: 2 + linesDeleted: 1333 + rank: 3 + newContributor: false + - username: VladUreche + gravatar: https://secure.gravatar.com/avatar/5658ed1cea041577df360fd663c570fa?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 2 + linesAdded: 86 + linesDeleted: 32 + rank: 3 + newContributor: false + - username: axel22 + gravatar: https://secure.gravatar.com/avatar/e9bdb4fada7e635fffb5e6f26e70cd1d?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 9 + linesDeleted: 106 + rank: 4 + newContributor: false + - category: Community + authors: + - username: vigdorchik + gravatar: https://secure.gravatar.com/avatar/d497b1b875b7f68414daff74485b8501?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 4 + linesAdded: 471 + linesDeleted: 410 + rank: 1 + newContributor: false + - username: vy + gravatar: https://secure.gravatar.com/avatar/bb8d759cf4230bcaa238fac0018af80c?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 2 + linesAdded: 21 + linesDeleted: 21 + rank: 2 + newContributor: true + - username: u-abramchuk + gravatar: https://secure.gravatar.com/avatar/c70eb13a60582914b51966fdc1a18536?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 2 + linesAdded: 47 + linesDeleted: 13 + rank: 2 + newContributor: true + - username: viktorklang + gravatar: https://secure.gravatar.com/avatar/4f674b2e79f1663864ff78e07ce4c8a8?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 2 + linesAdded: 38 + linesDeleted: 10 + rank: 2 + newContributor: false + - username: jozic + gravatar: https://secure.gravatar.com/avatar/41fbba6d48e543a7dfa8c231b2d0286d?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 8 + linesDeleted: 8 + rank: 3 + newContributor: true + - username: rnix + gravatar: https://secure.gravatar.com/avatar/0dcbf348a28f2295164c53a40d48a958?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 1 + linesDeleted: 1 + rank: 3 + newContributor: true + - username: mergeconflict + gravatar: https://secure.gravatar.com/avatar/9a58682929b182af7b01f0180e072fcd?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 22 + linesDeleted: 15 + rank: 3 + newContributor: false + - username: huitseeker + gravatar: https://secure.gravatar.com/avatar/dc11aab8ab70b10a828b5ee4735183e8?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 26 + linesDeleted: 0 + rank: 3 + newContributor: false + - username: ViniciusMiana + gravatar: https://secure.gravatar.com/avatar/e05e828a92458c4075b498c7d2957ddd?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 16 + linesDeleted: 0 + rank: 3 + newContributor: false + - username: mt2309 + gravatar: https://secure.gravatar.com/avatar/f70e1d36b9c1b9290d31e810fa1502f3?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 3 + linesDeleted: 0 + rank: 3 + newContributor: false + - username: Blaisorblade + gravatar: https://secure.gravatar.com/avatar/a3a676c96a88feb813010e67af012ca0?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 0 + linesDeleted: 3 + rank: 3 + newContributor: false + - username: rkuhn + gravatar: https://secure.gravatar.com/avatar/262b1ab25e66b1e15a48fa3f68703aad?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 3 + linesDeleted: 2 + rank: 3 + newContributor: false + - username: khernyo + gravatar: https://secure.gravatar.com/avatar/0e0d750a49edb4b16e8ec83816ea356e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 25 + linesDeleted: 1 + rank: 3 + newContributor: false + - username: som-snytt + gravatar: https://secure.gravatar.com/avatar/ec5b08d0fe94845ba49fd4a263c7d99d?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 1 + linesDeleted: 1 + rank: 3 + newContributor: false +--- diff --git a/contribute/scala-fame-data/_posts/2013-04-01-scala-fame-2013-03.md b/contribute/scala-fame-data/_posts/2013-04-01-scala-fame-2013-03.md new file mode 100644 index 0000000000..51b489e84c --- /dev/null +++ b/contribute/scala-fame-data/_posts/2013-04-01-scala-fame-2013-03.md @@ -0,0 +1,126 @@ +--- +layout: famearchive +title: Contributors of March 2013 +fame-year: 2013 +fame-month: 3 +fame-month-str: March +fame-categories: + - category: Typesafe + authors: + - username: paulp + gravatar: https://secure.gravatar.com/avatar/c25d674f69bb9c155f265a7482712be4?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 51 + linesAdded: 38101 + linesDeleted: 37753 + rank: 1 + newContributor: false + - username: retronym + gravatar: https://secure.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 45 + linesAdded: 4824 + linesDeleted: 3092 + rank: 2 + newContributor: false + - username: adriaanm + gravatar: https://secure.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 26 + linesAdded: 2632 + linesDeleted: 5012 + rank: 3 + newContributor: false + - username: JamesIry + gravatar: https://secure.gravatar.com/avatar/72b1a6b08fd8bb3068bd281974461c3e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 7 + linesAdded: 1218 + linesDeleted: 171 + rank: 4 + newContributor: false + - username: dragos + gravatar: https://secure.gravatar.com/avatar/fbd384e9626d28d1648f023a5e22672f?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 169 + linesDeleted: 2 + rank: 5 + newContributor: false + - category: EPFL + authors: + - username: xeno-by + gravatar: https://secure.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 7 + linesAdded: 212 + linesDeleted: 104 + rank: 1 + newContributor: false + - category: Community + authors: + - username: vigdorchik + gravatar: https://secure.gravatar.com/avatar/d497b1b875b7f68414daff74485b8501?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 9 + linesAdded: 714 + linesDeleted: 619 + rank: 1 + newContributor: false + - username: som-snytt + gravatar: https://secure.gravatar.com/avatar/ec5b08d0fe94845ba49fd4a263c7d99d?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 7 + linesAdded: 2103 + linesDeleted: 2068 + rank: 2 + newContributor: false + - username: soc + gravatar: https://secure.gravatar.com/avatar/6e4171314f4704b1e82aa4e5d9067e92?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 5 + linesAdded: 162 + linesDeleted: 96 + rank: 3 + newContributor: false + - username: kzys + gravatar: https://secure.gravatar.com/avatar/7828b45f8396aa361d85cead01fd99ca?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 5 + linesAdded: 129 + linesDeleted: 41 + rank: 3 + newContributor: false + - username: Blaisorblade + gravatar: https://secure.gravatar.com/avatar/a3a676c96a88feb813010e67af012ca0?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 3 + linesAdded: 72 + linesDeleted: 20 + rank: 4 + newContributor: false + - username: mesagie + gravatar: https://secure.gravatar.com/avatar/6e7dc465ed74b5250147168a0178d91c?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 4 + linesDeleted: 5 + rank: 5 + newContributor: true + - username: srinivasreddy + gravatar: https://secure.gravatar.com/avatar/1f542afb3240b82fdf08632bf6cd5384?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 1 + linesDeleted: 1 + rank: 5 + newContributor: true + - username: mergeconflict + gravatar: https://secure.gravatar.com/avatar/9a58682929b182af7b01f0180e072fcd?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 22 + linesDeleted: 15 + rank: 5 + newContributor: false + - username: sschaef + gravatar: https://secure.gravatar.com/avatar/dd80aab570fdb5f37e62de5422f44ed4?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 13 + linesDeleted: 0 + rank: 5 + newContributor: false + - username: chuvoks + gravatar: https://secure.gravatar.com/avatar/415869059046602f37803890bd992fc0?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 45 + linesDeleted: 24 + rank: 5 + newContributor: false +--- diff --git a/contribute/scala-fame-data/_posts/2013-05-01-scala-fame-2013-04.md b/contribute/scala-fame-data/_posts/2013-05-01-scala-fame-2013-04.md new file mode 100644 index 0000000000..ca59c6cdfb --- /dev/null +++ b/contribute/scala-fame-data/_posts/2013-05-01-scala-fame-2013-04.md @@ -0,0 +1,91 @@ +--- +layout: famearchive +title: Contributors of April 2013 +fame-year: 2013 +fame-month: 4 +fame-month-str: April +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://secure.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 36 + linesAdded: 1274 + linesDeleted: 776 + rank: 1 + newContributor: false + - username: paulp + gravatar: https://secure.gravatar.com/avatar/c25d674f69bb9c155f265a7482712be4?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 26 + linesAdded: 1848 + linesDeleted: 1647 + rank: 2 + newContributor: false + - username: vigdorchik + gravatar: https://secure.gravatar.com/avatar/d497b1b875b7f68414daff74485b8501?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 6 + linesAdded: 136 + linesDeleted: 186 + rank: 3 + newContributor: false + - username: adriaanm + gravatar: https://secure.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 3 + linesDeleted: 1 + rank: 4 + newContributor: false + - category: EPFL + authors: + - username: magarciaEPFL + gravatar: https://secure.gravatar.com/avatar/94ff1d59d6e0a3a4ab10c80ab12bfeed?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 9 + linesAdded: 147 + linesDeleted: 149 + rank: 1 + newContributor: false + - username: heathermiller + gravatar: https://secure.gravatar.com/avatar/54d0b6494927c0040b96ed327202e8dc?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 1 + linesDeleted: 1 + rank: 2 + newContributor: false + - username: hubertp + gravatar: https://secure.gravatar.com/avatar/e0dec64f93778e5c689c3873078a406f?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 54 + linesDeleted: 46 + rank: 2 + newContributor: false + - category: Community + authors: + - username: som-snytt + gravatar: https://secure.gravatar.com/avatar/ec5b08d0fe94845ba49fd4a263c7d99d?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 11 + linesAdded: 1000 + linesDeleted: 509 + rank: 1 + newContributor: false + - username: soc + gravatar: https://secure.gravatar.com/avatar/6e4171314f4704b1e82aa4e5d9067e92?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 3 + linesAdded: 37 + linesDeleted: 22 + rank: 2 + newContributor: false + - username: huitseeker + gravatar: https://secure.gravatar.com/avatar/dc11aab8ab70b10a828b5ee4735183e8?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 2 + linesAdded: 15 + linesDeleted: 19 + rank: 3 + newContributor: false + - username: namin + gravatar: https://secure.gravatar.com/avatar/f2adf4eb83e1221b519d23bf0bdc98d2?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 6 + linesDeleted: 11 + rank: 4 + newContributor: false +--- diff --git a/contribute/scala-fame.md b/contribute/scala-fame.md new file mode 100644 index 0000000000..98fad6e629 --- /dev/null +++ b/contribute/scala-fame.md @@ -0,0 +1,14 @@ +--- +layout: page +title: Scala Contribuitor Hall of Fame +--- +# Scala Hall of Fame + +A big thank you to everyone who contributed to: + - [the Scala library and compiler](https://github.com/scala/scala/contributors) + - [the Scala documentation website](https://github.com/scala/scala.github.com/contributors) + +{% for data in site.categories.scala-fame-data limit:1 %} + {% assign famedata = data %} + {% include render-scala-fame.html %} +{% endfor %} From 8559ddab546a4548f3cca197793f3809e3fe8d7f Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Thu, 30 May 2013 13:26:48 +0100 Subject: [PATCH 0021/3075] Going back to having a 'Contribute' section, take 2 --- contribute/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/index.md b/contribute/index.md index c3be3be994..6e07e5b84c 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -1,6 +1,6 @@ --- layout: page -title: Get Involved +title: Contribute --- # Contributing to the Scala project From 96c6854e2422b5a813d80ac737e4f58958a17c71 Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Wed, 5 Jun 2013 11:50:04 +0200 Subject: [PATCH 0022/3075] Making contribute page full width --- contribute/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/index.md b/contribute/index.md index 6e07e5b84c..9b6024dcf9 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -1,5 +1,5 @@ --- -layout: page +layout: page-full-width title: Contribute --- # Contributing to the Scala project From 2ddf889be5bad81e58ee391e1cf2cee85d3c5b36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 6 Jun 2013 09:09:53 +0200 Subject: [PATCH 0023/3075] Added hall of fame of May 2013. --- .../_posts/2013-06-01-scala-fame-2013-05.md | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 contribute/scala-fame-data/_posts/2013-06-01-scala-fame-2013-05.md diff --git a/contribute/scala-fame-data/_posts/2013-06-01-scala-fame-2013-05.md b/contribute/scala-fame-data/_posts/2013-06-01-scala-fame-2013-05.md new file mode 100644 index 0000000000..2829d6a4aa --- /dev/null +++ b/contribute/scala-fame-data/_posts/2013-06-01-scala-fame-2013-05.md @@ -0,0 +1,105 @@ +--- +layout: famearchive +title: Contributors of May 2013 +fame-year: 2013 +fame-month: 5 +fame-month-str: May +fame-categories: + - category: Typesafe + authors: + - username: paulp + gravatar: https://secure.gravatar.com/avatar/c25d674f69bb9c155f265a7482712be4?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 54 + linesAdded: 3465 + linesDeleted: 2035 + rank: 1 + newContributor: false + - username: retronym + gravatar: https://secure.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 13 + linesAdded: 525 + linesDeleted: 66 + rank: 2 + newContributor: false + - username: adriaanm + gravatar: https://secure.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 5 + linesAdded: 245 + linesDeleted: 81 + rank: 3 + newContributor: false + - username: viktorklang + gravatar: https://secure.gravatar.com/avatar/4f674b2e79f1663864ff78e07ce4c8a8?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 2 + linesAdded: 51 + linesDeleted: 32 + rank: 4 + newContributor: false + - username: phaller + gravatar: https://secure.gravatar.com/avatar/3b84657fdb075382e3781310ca8a9a70?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 1965 + linesDeleted: 1086 + rank: 5 + newContributor: false + - category: EPFL + authors: + - username: xeno-by + gravatar: https://secure.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 19 + linesAdded: 742 + linesDeleted: 468 + rank: 1 + newContributor: false + - username: magarciaEPFL + gravatar: https://secure.gravatar.com/avatar/94ff1d59d6e0a3a4ab10c80ab12bfeed?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 11 + linesAdded: 1214 + linesDeleted: 1069 + rank: 2 + newContributor: false + - username: heathermiller + gravatar: https://secure.gravatar.com/avatar/54d0b6494927c0040b96ed327202e8dc?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 10 + linesDeleted: 7 + rank: 3 + newContributor: false + - category: Community + authors: + - username: soc + gravatar: https://secure.gravatar.com/avatar/6e4171314f4704b1e82aa4e5d9067e92?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 12 + linesAdded: 254 + linesDeleted: 1135 + rank: 1 + newContributor: false + - username: som-snytt + gravatar: https://secure.gravatar.com/avatar/ec5b08d0fe94845ba49fd4a263c7d99d?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 6 + linesAdded: 454 + linesDeleted: 403 + rank: 2 + newContributor: false + - username: vigdorchik + gravatar: https://secure.gravatar.com/avatar/d497b1b875b7f68414daff74485b8501?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 2 + linesAdded: 42 + linesDeleted: 32 + rank: 3 + newContributor: false + - username: dcsobral + gravatar: https://secure.gravatar.com/avatar/6d43da5df0e52fc31c55e6a227bb23f4?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 6 + linesDeleted: 2 + rank: 4 + newContributor: false + - username: kzys + gravatar: https://secure.gravatar.com/avatar/7828b45f8396aa361d85cead01fd99ca?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 25 + linesDeleted: 9 + rank: 4 + newContributor: false +--- From 81e54742affd89a43d638b815593089857f277cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 6 Jun 2013 09:17:01 +0200 Subject: [PATCH 0024/3075] 3-column layout for hall of fame pages. --- contribute/scala-fame.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/scala-fame.md b/contribute/scala-fame.md index 98fad6e629..084c120e27 100644 --- a/contribute/scala-fame.md +++ b/contribute/scala-fame.md @@ -1,5 +1,5 @@ --- -layout: page +layout: page-full-width title: Scala Contribuitor Hall of Fame --- # Scala Hall of Fame From 5a8dd183d57819c319f69e3d92ee73aabf6c934f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 6 Jun 2013 09:28:28 +0200 Subject: [PATCH 0025/3075] Added namin in EPFL people. --- .../_posts/2013-03-01-scala-fame-2013-02.md | 63 +++++----- .../_posts/2013-04-01-scala-fame-2013-03.md | 63 ++++++---- .../_posts/2013-05-01-scala-fame-2013-04.md | 115 ++++++++++++------ 3 files changed, 152 insertions(+), 89 deletions(-) diff --git a/contribute/scala-fame-data/_posts/2013-03-01-scala-fame-2013-02.md b/contribute/scala-fame-data/_posts/2013-03-01-scala-fame-2013-02.md index fbdccb279c..376563abce 100644 --- a/contribute/scala-fame-data/_posts/2013-03-01-scala-fame-2013-02.md +++ b/contribute/scala-fame-data/_posts/2013-03-01-scala-fame-2013-02.md @@ -35,20 +35,41 @@ fame-categories: linesDeleted: 1097 rank: 4 newContributor: false + - username: viktorklang + gravatar: https://secure.gravatar.com/avatar/4f674b2e79f1663864ff78e07ce4c8a8?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 3 + linesAdded: 84 + linesDeleted: 53 + rank: 5 + newContributor: false - username: gkossakowski gravatar: https://secure.gravatar.com/avatar/e608c8cb27858cc5aaf7d0c1e57958d7?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png commits: 2 linesAdded: 4 linesDeleted: 1 - rank: 5 + rank: 6 + newContributor: false + - username: huitseeker + gravatar: https://secure.gravatar.com/avatar/dc11aab8ab70b10a828b5ee4735183e8?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 26 + linesDeleted: 0 + rank: 7 + newContributor: false + - username: rkuhn + gravatar: https://secure.gravatar.com/avatar/262b1ab25e66b1e15a48fa3f68703aad?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 3 + linesDeleted: 2 + rank: 7 newContributor: false - category: EPFL authors: - username: xeno-by gravatar: https://secure.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 29 - linesAdded: 2108 - linesDeleted: 724 + commits: 36 + linesAdded: 3379 + linesDeleted: 1635 rank: 1 newContributor: false - username: lrytz @@ -72,6 +93,13 @@ fame-categories: linesDeleted: 32 rank: 3 newContributor: false + - username: hubertp + gravatar: https://secure.gravatar.com/avatar/e0dec64f93778e5c689c3873078a406f?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 2 + linesAdded: 297 + linesDeleted: 100 + rank: 3 + newContributor: false - username: axel22 gravatar: https://secure.gravatar.com/avatar/e9bdb4fada7e635fffb5e6f26e70cd1d?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png commits: 1 @@ -102,13 +130,6 @@ fame-categories: linesDeleted: 13 rank: 2 newContributor: true - - username: viktorklang - gravatar: https://secure.gravatar.com/avatar/4f674b2e79f1663864ff78e07ce4c8a8?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 2 - linesAdded: 38 - linesDeleted: 10 - rank: 2 - newContributor: false - username: jozic gravatar: https://secure.gravatar.com/avatar/41fbba6d48e543a7dfa8c231b2d0286d?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png commits: 1 @@ -130,10 +151,10 @@ fame-categories: linesDeleted: 15 rank: 3 newContributor: false - - username: huitseeker - gravatar: https://secure.gravatar.com/avatar/dc11aab8ab70b10a828b5ee4735183e8?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + - username: mt2309 + gravatar: https://secure.gravatar.com/avatar/f70e1d36b9c1b9290d31e810fa1502f3?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png commits: 1 - linesAdded: 26 + linesAdded: 3 linesDeleted: 0 rank: 3 newContributor: false @@ -144,13 +165,6 @@ fame-categories: linesDeleted: 0 rank: 3 newContributor: false - - username: mt2309 - gravatar: https://secure.gravatar.com/avatar/f70e1d36b9c1b9290d31e810fa1502f3?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 3 - linesDeleted: 0 - rank: 3 - newContributor: false - username: Blaisorblade gravatar: https://secure.gravatar.com/avatar/a3a676c96a88feb813010e67af012ca0?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png commits: 1 @@ -158,13 +172,6 @@ fame-categories: linesDeleted: 3 rank: 3 newContributor: false - - username: rkuhn - gravatar: https://secure.gravatar.com/avatar/262b1ab25e66b1e15a48fa3f68703aad?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 3 - linesDeleted: 2 - rank: 3 - newContributor: false - username: khernyo gravatar: https://secure.gravatar.com/avatar/0e0d750a49edb4b16e8ec83816ea356e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png commits: 1 diff --git a/contribute/scala-fame-data/_posts/2013-04-01-scala-fame-2013-03.md b/contribute/scala-fame-data/_posts/2013-04-01-scala-fame-2013-03.md index 51b489e84c..0feb88618a 100644 --- a/contribute/scala-fame-data/_posts/2013-04-01-scala-fame-2013-03.md +++ b/contribute/scala-fame-data/_posts/2013-04-01-scala-fame-2013-03.md @@ -16,16 +16,16 @@ fame-categories: newContributor: false - username: retronym gravatar: https://secure.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 45 - linesAdded: 4824 + commits: 46 + linesAdded: 4908 linesDeleted: 3092 rank: 2 newContributor: false - username: adriaanm gravatar: https://secure.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 26 - linesAdded: 2632 - linesDeleted: 5012 + commits: 27 + linesAdded: 2675 + linesDeleted: 5043 rank: 3 newContributor: false - username: JamesIry @@ -46,11 +46,18 @@ fame-categories: authors: - username: xeno-by gravatar: https://secure.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 7 - linesAdded: 212 - linesDeleted: 104 + commits: 11 + linesAdded: 295 + linesDeleted: 129 rank: 1 newContributor: false + - username: magarciaEPFL + gravatar: https://secure.gravatar.com/avatar/94ff1d59d6e0a3a4ab10c80ab12bfeed?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 6 + linesAdded: 89 + linesDeleted: 44 + rank: 2 + newContributor: false - category: Community authors: - username: vigdorchik @@ -69,8 +76,8 @@ fame-categories: newContributor: false - username: soc gravatar: https://secure.gravatar.com/avatar/6e4171314f4704b1e82aa4e5d9067e92?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 5 - linesAdded: 162 + commits: 6 + linesAdded: 166 linesDeleted: 96 rank: 3 newContributor: false @@ -79,48 +86,62 @@ fame-categories: commits: 5 linesAdded: 129 linesDeleted: 41 - rank: 3 + rank: 4 newContributor: false - username: Blaisorblade gravatar: https://secure.gravatar.com/avatar/a3a676c96a88feb813010e67af012ca0?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png commits: 3 linesAdded: 72 linesDeleted: 20 - rank: 4 + rank: 5 newContributor: false - - username: mesagie - gravatar: https://secure.gravatar.com/avatar/6e7dc465ed74b5250147168a0178d91c?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + - username: starblood + gravatar: https://secure.gravatar.com/avatar/bd3514b960213c6a7ff5fd3186675429?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png commits: 1 - linesAdded: 4 - linesDeleted: 5 - rank: 5 + linesAdded: 1 + linesDeleted: 1 + rank: 6 newContributor: true - username: srinivasreddy gravatar: https://secure.gravatar.com/avatar/1f542afb3240b82fdf08632bf6cd5384?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png commits: 1 linesAdded: 1 linesDeleted: 1 - rank: 5 + rank: 6 + newContributor: true + - username: mesagie + gravatar: https://secure.gravatar.com/avatar/6e7dc465ed74b5250147168a0178d91c?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 4 + linesDeleted: 5 + rank: 6 newContributor: true - username: mergeconflict gravatar: https://secure.gravatar.com/avatar/9a58682929b182af7b01f0180e072fcd?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png commits: 1 linesAdded: 22 linesDeleted: 15 - rank: 5 + rank: 6 newContributor: false - username: sschaef gravatar: https://secure.gravatar.com/avatar/dd80aab570fdb5f37e62de5422f44ed4?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png commits: 1 linesAdded: 13 linesDeleted: 0 - rank: 5 + rank: 6 + newContributor: false + - username: ihji + gravatar: https://secure.gravatar.com/avatar/866a258f0c9fa9529aa47ebd96fe599c?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 33 + linesDeleted: 6 + rank: 6 newContributor: false - username: chuvoks gravatar: https://secure.gravatar.com/avatar/415869059046602f37803890bd992fc0?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png commits: 1 linesAdded: 45 linesDeleted: 24 - rank: 5 + rank: 6 newContributor: false --- diff --git a/contribute/scala-fame-data/_posts/2013-05-01-scala-fame-2013-04.md b/contribute/scala-fame-data/_posts/2013-05-01-scala-fame-2013-04.md index ca59c6cdfb..e2cd419e9b 100644 --- a/contribute/scala-fame-data/_posts/2013-05-01-scala-fame-2013-04.md +++ b/contribute/scala-fame-data/_posts/2013-05-01-scala-fame-2013-04.md @@ -7,85 +7,120 @@ fame-month-str: April fame-categories: - category: Typesafe authors: - - username: retronym - gravatar: https://secure.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 36 - linesAdded: 1274 - linesDeleted: 776 - rank: 1 - newContributor: false - username: paulp gravatar: https://secure.gravatar.com/avatar/c25d674f69bb9c155f265a7482712be4?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 26 - linesAdded: 1848 - linesDeleted: 1647 + commits: 38 + linesAdded: 3745 + linesDeleted: 2973 + rank: 1 + newContributor: false + - username: retronym + gravatar: https://secure.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 37 + linesAdded: 1309 + linesDeleted: 777 rank: 2 newContributor: false - - username: vigdorchik - gravatar: https://secure.gravatar.com/avatar/d497b1b875b7f68414daff74485b8501?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 6 - linesAdded: 136 - linesDeleted: 186 + - username: huitseeker + gravatar: https://secure.gravatar.com/avatar/dc11aab8ab70b10a828b5ee4735183e8?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 3 + linesAdded: 16 + linesDeleted: 24 rank: 3 newContributor: false - username: adriaanm gravatar: https://secure.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 1 - linesAdded: 3 - linesDeleted: 1 + commits: 2 + linesAdded: 35 + linesDeleted: 82 rank: 4 newContributor: false - category: EPFL authors: - username: magarciaEPFL gravatar: https://secure.gravatar.com/avatar/94ff1d59d6e0a3a4ab10c80ab12bfeed?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 9 - linesAdded: 147 - linesDeleted: 149 + commits: 11 + linesAdded: 238 + linesDeleted: 204 rank: 1 newContributor: false + - username: xeno-by + gravatar: https://secure.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 4 + linesAdded: 208 + linesDeleted: 121 + rank: 2 + newContributor: false + - username: namin + gravatar: https://secure.gravatar.com/avatar/f2adf4eb83e1221b519d23bf0bdc98d2?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 6 + linesDeleted: 11 + rank: 3 + newContributor: false - username: heathermiller gravatar: https://secure.gravatar.com/avatar/54d0b6494927c0040b96ed327202e8dc?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png commits: 1 linesAdded: 1 linesDeleted: 1 - rank: 2 + rank: 3 newContributor: false - username: hubertp gravatar: https://secure.gravatar.com/avatar/e0dec64f93778e5c689c3873078a406f?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png commits: 1 linesAdded: 54 linesDeleted: 46 - rank: 2 + rank: 3 newContributor: false - category: Community authors: - username: som-snytt gravatar: https://secure.gravatar.com/avatar/ec5b08d0fe94845ba49fd4a263c7d99d?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 11 - linesAdded: 1000 - linesDeleted: 509 + commits: 16 + linesAdded: 2561 + linesDeleted: 1150 rank: 1 newContributor: false + - username: vigdorchik + gravatar: https://secure.gravatar.com/avatar/d497b1b875b7f68414daff74485b8501?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 9 + linesAdded: 235 + linesDeleted: 321 + rank: 2 + newContributor: false - username: soc gravatar: https://secure.gravatar.com/avatar/6e4171314f4704b1e82aa4e5d9067e92?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png - commits: 3 - linesAdded: 37 - linesDeleted: 22 - rank: 2 + commits: 4 + linesAdded: 38 + linesDeleted: 26 + rank: 3 newContributor: false - - username: huitseeker - gravatar: https://secure.gravatar.com/avatar/dc11aab8ab70b10a828b5ee4735183e8?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + - username: ihji + gravatar: https://secure.gravatar.com/avatar/866a258f0c9fa9529aa47ebd96fe599c?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png commits: 2 - linesAdded: 15 - linesDeleted: 19 - rank: 3 + linesAdded: 13 + linesDeleted: 2 + rank: 4 newContributor: false - - username: namin - gravatar: https://secure.gravatar.com/avatar/f2adf4eb83e1221b519d23bf0bdc98d2?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + - username: bjornregnell + gravatar: https://secure.gravatar.com/avatar/b1d20c98b0eeb72829523144b9174ca2?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png commits: 1 - linesAdded: 6 - linesDeleted: 11 - rank: 4 + linesAdded: 3 + linesDeleted: 2 + rank: 5 + newContributor: true + - username: aldenml + gravatar: https://secure.gravatar.com/avatar/bbf061bd484515c156f662a65820c226?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 4 + linesDeleted: 4 + rank: 5 + newContributor: true + - username: eed3si9n + gravatar: https://secure.gravatar.com/avatar/8f41595db400be30176f6f04630c2842?s=60&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png + commits: 1 + linesAdded: 304 + linesDeleted: 6 + rank: 5 newContributor: false --- From 5056003f15841f8f8362b0240f141e2b0aced0a2 Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Sat, 8 Jun 2013 00:45:43 +0200 Subject: [PATCH 0026/3075] Styling contents and other cleanups --- contribute/bug-reporting-guide.md | 2 -- contribute/hacker-guide.md | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/contribute/bug-reporting-guide.md b/contribute/bug-reporting-guide.md index e286ce2002..f04503f968 100644 --- a/contribute/bug-reporting-guide.md +++ b/contribute/bug-reporting-guide.md @@ -3,8 +3,6 @@ layout: page title: Bug Reporting --- -# Reporting Bugs to the Scala Project - The Scala project tracker is located at [http://issues.scala-lang.org](http://issues.scala-lang.org). Before you submit a bug make sure that it is certainly a bug by following instructions in *Is it a Bug?*. ## Is it a Bug? diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 758bb17115..484d3036a1 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -1,10 +1,9 @@ --- layout: page title: Scala hacker guide +by: Eugene Burmako --- - -**Eugene Burmako** - +
This guide is intended to help you get from an idea of fixing a bug or implementing a new feature into a nightly Scala build, and, ultimately, to a production release of Scala incorporating your idea. This guide covers the entire process, from the conception of your idea or bugfix to the point where it is merged into Scala. Throughout, we will use a running example of an idea or bugfix one might wish to contribute. From 43b72d980cd057dc11dafb6f73d37bbad1f6e491 Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Sat, 8 Jun 2013 20:32:38 +0200 Subject: [PATCH 0027/3075] Formatting fix to hackers guide --- contribute/hacker-guide.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 484d3036a1..d3ee84456f 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -287,9 +287,9 @@ run `ant test` to go through the entire test suite (30+ minutes) or use wildcard After development is finished, it's time to publish the code and submit your patch for discussion and potential inclusion into Scala. In a nutshell, this involves: - 1. making sure that your code and commit messages are of high quality, - 2. clicking a few buttons in the Github interface, - 3. assigning one or more reviewers which will look through your pull request. +1. making sure that your code and commit messages are of high quality, +2. clicking a few buttons in the Github interface, +3. assigning one or more reviewers which will look through your pull request. Let's go into each of these points in more detail. @@ -298,9 +298,8 @@ In a nutshell, this involves: The [Git Basics](http://git-scm.com/book/en/Git-Basics) chapter in the Git online book covers most of the basic workflow during this stage. There are two things you should know here: - 1. Commit messages are often the only way to understand the intentions of authors of code written a few years ago. Thus, writing a quality is of utmost importance. The more context you provide for the change you've introduced, the larger the chance that some future maintainer understand your intentions. Consult [the pull request policy](https://github.com/scala/scala/wiki/Pull-Request-Policy) for more information about the desired style of your commits. - - 2. Keeping Scala's git history clean is also important. Therefore we won't accept pull requests for bug fixes that have more than one commit. For features, it is okay to have several commits, but all tests need to pass after every single commit. To clean up your commit structure, you want to [rewrite history](http://git-scm.com/book/en/Git-Branching-Rebasing) using `git rebase` so that your commits are against the latest revision of `master`. +1. Commit messages are often the only way to understand the intentions of authors of code written a few years ago. Thus, writing a quality is of utmost importance. The more context you provide for the change you've introduced, the larger the chance that some future maintainer understand your intentions. Consult [the pull request policy](https://github.com/scala/scala/wiki/Pull-Request-Policy) for more information about the desired style of your commits. +2. Keeping Scala's git history clean is also important. Therefore we won't accept pull requests for bug fixes that have more than one commit. For features, it is okay to have several commits, but all tests need to pass after every single commit. To clean up your commit structure, you want to [rewrite history](http://git-scm.com/book/en/Git-Branching-Rebasing) using `git rebase` so that your commits are against the latest revision of `master`. Once you are satisfied with your work, synced with `master` and cleaned up your commits you are ready to submit a patch to the central Scala repository. Before proceeding make sure you have pushed all of your local changes to your fork on Github. From 05854a11c3be0fbd2dfb0f10b27d5fc89cdffcac Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Fri, 12 Jul 2013 12:25:39 +0200 Subject: [PATCH 0028/3075] Moving community tickets back to contribute section --- contribute/index.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/contribute/index.md b/contribute/index.md index 9b6024dcf9..7338d06c2c 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -93,6 +93,10 @@ the Scala project source tree. The [hacker guide](hacker-guide.html) will explai
+## Community Tickets + +
+ diff --git a/contribute/index.md b/contribute/index.md index 656109cf02..c7b822ae04 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -1,199 +1,19 @@ --- -layout: page-full-width +layout: page title: Contribute --- -# Contributing to the Scala project -The Scala programming language is an open source project with a very -diverse community, where people from all over the world contribute their work, -with everyone benefitting from friendly help and advice, and -kindly helping others in return. So why not join the Scala community and help -everyone make things better? +## How to help? -
-
-
-

Scala Internals

-

Get a peek into the inners of the Scala compiler.

-
-
-

Report an issue

-

File a bug report or a feature request.

-
-
-

Documentation

-

Improve the documentation itself.

-
-
+### Reporting bugs -
-
-

Write a SIP

-

Write a proposal for extending/improving Scala.

-
-
-

Hacker's guide

-

Learn to write good code and improve your chances of contributing to the Scala galaxy.

-
-
-

Community issues

-

Get cracking on some easy to approach issues.

-
-
+See our [bug reporting guide](./bug-reporting-guide.html) to learn +how to efficiently report a bug. -
-
-

Unassigned issues

-

Get serious with some more complex issues.

-
-
-

Hall of Fame

-

Track your rockstar status in the community.

-
-
-

Test your contributions

-

Learn how to run the Scala test suite.

-
-
-
+### Patch the core +Want to dive into the hardcore business? Check out our +[selection of community tickets](./community-tickets.html), +which are good starting points to contributing. - -### Why contribute a patch to Scala? - -Just to name a few common reasons: - - contributing a patch is the best way to make sure your desired changes will be available in the next Scala version - - Scala is written in Scala, so going through the source code and patching it will improve your Scala-fu - - last but not least, you will make it into the [Scala Contributor Hall of Fame](scala-fame.html). - -
- -The main Scala project consists of the standard Scala library, the Scala reflection and macros library, -the Scala compiler and the Scaladoc tool. This means there's plenty to choose from when deciding what to work on. -Typically the scaladoc tool provides a low entry point for new committers, so it is a good first step into contributing. - -On the Scala bug tracker you will find many bugs that are [marked as good starting points to contributing ("community" bugs)](https://issues.scala-lang.org/secure/IssueNavigator.jspa?requestId=12111) or [that are not currently assigned](https://issues.scala-lang.org/secure/IssueNavigator.jspa?requestId=12112) and that you could pick up. Once you decided on a ticket to look at, see the next step on how to proceed further. - -If you are interested in contributing code, we ask you to sign the -[Scala Contributor License Agreement](http://typesafe.com/contribute/cla/scala), -which allows us to ensure that all code submitted to the project is -unencumbered by copyrights or patents. - -
- -### I have this idea that I'd like to add to Scala, how do I start? - -The first step to making a change is to discuss it with the community at large, to make sure everyone agrees on the idea -and on the implementation plan. Starting point ("community") bugs are usually uncontroversial, so you can jump right -ahead to hacking the scala source tree and filing a pull request. For larger changes it is best to announce the change -on the [scala-internals](http://groups.google.com/group/scala-internals) mailing list and get developer feedback. For really complex changes, a [Scala Improvement Process (SIP)](http://docs.scala-lang.org/sips/) document might be required, but the first step is always to discuss it on the mailing list. - -Contributions, big or small, simple or complex, controversial or undisputed, need to materialize as patches against -the Scala project source tree. The [hacker guide](hacker-guide.html) will explain how to materialize your idea into a full-fledged pull request against the Scala code base. - - +More info in our [contributing guide](./guide.html). From 22dc8088db52f999a4290dc3455e1231557b1aae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Wed, 17 Jul 2013 17:31:21 +0200 Subject: [PATCH 0032/3075] A bit of rewording on the contribute page. --- contribute/index.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/contribute/index.md b/contribute/index.md index c7b822ae04..3cd58f8631 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -10,10 +10,16 @@ title: Contribute See our [bug reporting guide](./bug-reporting-guide.html) to learn how to efficiently report a bug. -### Patch the core +### Help with the documentation + +An easy but very important way to contribute to Scala is to +[help with the documentation](http://docs.scala-lang.org/contribute.html). + +### Compiler and other tools Want to dive into the hardcore business? Check out our [selection of community tickets](./community-tickets.html), -which are good starting points to contributing. +which are good starting points to contributing to the compiler and +surrounding tools, like ScalaDoc. More info in our [contributing guide](./guide.html). From 684bb8b49fdd1baf968b04b74395adccd1e8962a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 18 Jul 2013 11:03:40 +0200 Subject: [PATCH 0033/3075] Dropped 3 boxes on the Contribute guide. * SIP * Unassigned tickets * Partest The two first are not supposed to be entry points, and they still have a link further down in the text. Partest is mentioned in the Hacker's guide. And there is no point in using partest without first going through the hacker's guide. --- contribute/guide.md | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/contribute/guide.md b/contribute/guide.md index 28adc54e6b..4841496253 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -27,32 +27,17 @@ everyone make things better?
-

Write a SIP

-

Write a proposal for extending/improving Scala.

+

Community issues

+

Get cracking on some easy to approach issues.

Hacker's guide

Learn to write good code and improve your chances of contributing to the Scala galaxy.

-
-

Community issues

-

Get cracking on some easy to approach issues.

-
-
- -
-
-

Unassigned issues

-

Get serious with some more complex issues.

-

Hall of Fame

Track your rockstar status in the community.

-
-

Test your contributions

-

Learn how to run the Scala test suite.

-
From 13462b997cddbc48e8392f6324fafb2a30b678b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 18 Jul 2013 11:10:07 +0200 Subject: [PATCH 0034/3075] Moved the contribute intro text to contribute/. Before it was in contribute/guide.html, but now contribute/ is the landing page for contributions. --- contribute/guide.md | 6 ------ contribute/index.md | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/contribute/guide.md b/contribute/guide.md index 4841496253..ac27e53719 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -3,12 +3,6 @@ layout: page-full-width title: Contributing guide --- -The Scala programming language is an open source project with a very -diverse community, where people from all over the world contribute their work, -with everyone benefitting from friendly help and advice, and -kindly helping others in return. So why not join the Scala community and help -everyone make things better? -
diff --git a/contribute/index.md b/contribute/index.md index 3cd58f8631..d2402cf4d2 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -3,6 +3,12 @@ layout: page title: Contribute --- +The Scala programming language is an open source project with a very +diverse community, where people from all over the world contribute their work, +with everyone benefitting from friendly help and advice, and +kindly helping others in return. So why not join the Scala community and help +everyone make things better? + ## How to help? ### Reporting bugs From 966a0f22e50d6cf9a2e2f0ac4cf042d369d69490 Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Tue, 30 Jul 2013 10:01:55 -0700 Subject: [PATCH 0035/3075] Removing double title on the hall of fame --- contribute/scala-fame.md | 1 - 1 file changed, 1 deletion(-) diff --git a/contribute/scala-fame.md b/contribute/scala-fame.md index 084c120e27..81bb76ee3a 100644 --- a/contribute/scala-fame.md +++ b/contribute/scala-fame.md @@ -2,7 +2,6 @@ layout: page-full-width title: Scala Contribuitor Hall of Fame --- -# Scala Hall of Fame A big thank you to everyone who contributed to: - [the Scala library and compiler](https://github.com/scala/scala/contributors) From 688d5568e0a74ea8a7b83f3d56f08378fc1eb516 Mon Sep 17 00:00:00 2001 From: Simon Ochsenreither Date: Wed, 31 Jul 2013 01:34:52 +0200 Subject: [PATCH 0036/3075] =?UTF-8?q?Add=20section=20=E2=80=9CTest?= =?UTF-8?q?=E2=80=9D=20and=20=E2=80=9CMerge=E2=80=9D,=20rename=20=E2=80=9C?= =?UTF-8?q?Discuss=E2=80=9D=20to=20=E2=80=9CReview=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contribute/hacker-guide.md | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index d3ee84456f..c471baceca 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -221,8 +221,8 @@ Tools like Scaladoc also welcome contributions. Unfortunately these smaller proj ### Interlude -To fix [the bug we're interested in](https://issues.scala-lang.org/browse/SI-6725). Let's say we've tracked the `StringContext.f` interpolator -down to a macro implemented in `MacroImplementations.scala`, and there we notice that the interpolator only processes conversions, +To fix [the bug we're interested in](https://issues.scala-lang.org/browse/SI-6725) we've tracked the `StringContext.f` interpolator +down to a macro implemented in `MacroImplementations.scala` There we notice that the interpolator only processes conversions, but not tokens like `%n`. Looks like an easy fix. 18:44 ~/Projects/scala/sandbox (ticket/6725)$ git diff @@ -265,6 +265,17 @@ After applying the fix and running `ant`, our simple test case in `sandbox/Test. 1 1 // no longer getting the %n here - it got transformed into a newline +### Test + +To guard your change against accidental breakage in the future, it is important to add tests. +I have already written one test earlier, so that's a good start but not enough! Apart from obvious usages of our new functionality, we need to cover corner-cases as well. + +Adding tests to the test suite is as easy as moving them to the appropriate directory: + +* Code which should compile successfully, but doesn't need to be executed, needs to go into the [“pos” directory](https://github.com/scala/scala/tree/master/test/files/pos) +* Code which should not compile needs to go into the [“neg” directory](https://github.com/scala/scala/tree/master/test/files/neg) +* Code which should compile and get executed by the test suite needs to go into the [“run” directory](https://github.com/scala/scala/tree/master/test/files/run) + ### Verify Now to make sure that my fix doesn't break anything I need to run the test suite using the `partest` tool we wrote to test Scala. @@ -326,10 +337,15 @@ need to sign the contributor license agreement, which [can be done online](http:
Submit a pull request
-### Discuss +### Review After the pull request has been submitted, you need to pick a reviewer (usually the person you've contacted in the beginning of your workflow) and be ready to elaborate and adjust your patch if necessary. In this example, we picked Martin, because we had such a nice chat on the mailing list:
SAssign the reviewer
+## Merge + +After your reviewer is happy with your code (usually signalled by a LGTM — “Looks good to me”), your job is done. +Note that there can be a gap between a successful review and the merge, because not every reviewer has merge rights. In that case, someone else from the team will pick up your pull request and merge it. +So don't be confused if your reviewer says “LGTM”, but your code doesn't get merged immediately. From 29705fcb98500b5c2c586cbf8f06c411a1b1d53e Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Wed, 31 Jul 2013 08:10:21 -0400 Subject: [PATCH 0037/3075] minor copyediting to hacker guide --- contribute/hacker-guide.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index c471baceca..28ea69bc3f 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -26,11 +26,11 @@ Sometimes it's appealing to hack alone and not to have to interact with others o this might not be the very best idea. There are people in the Scala community who have spent years accumulating knowledge about Scala libraries and internals. They might provide unique insights and, what's even better, direct assistance in their areas, so it is not only advantageous, but recommended to communicate with the community about your new patch. -Typically bug fixes new features start out as an idea or an experiment posted on one of our mailing lists [our mailing lists]({{ site.baseurl }}/community/index.html#mailing_lists) to find out how people feel -about things you want to implement. People proficient is certain areas of Scala usually monitor mailing lists, so you'll often get some help +Typically bug fixes and new features start out as an idea or an experiment posted on one of our mailing lists [our mailing lists]({{ site.baseurl }}/community/index.html#mailing_lists) to find out how people feel +about things you want to implement. People proficient in certain areas of Scala usually monitor mailing lists, so you'll often get some help by simply posting a message. But the most efficient way to connect is to cc your message to one of the people responsible for maintaining the aspect of Scala which you wish to contribute to. -This is the list of language features/libraries along with their maintainers's full names and github usernames: +This is the list of language features/libraries along with their maintainers's full names and GitHub usernames: {% include maintainers.html %} @@ -65,7 +65,7 @@ If you're new to Git, don't be afraid of messing up-- there is no way you can co If everything went okay, you will be redirected to your own fork at `https://github.com/username/scala`, where `username` is your github user name. You might find it helpful to read [http://help.github.com/fork-a-repo/](http://help.github.com/fork-a-repo/), -which covers some of the things that will follow below. Then, _clone_ your repository (_i.e._ pull a copy from github to your local machine) by running the following on the command line: +which covers some of the things that will follow below. Then, _clone_ your repository (_i.e._ pull a copy from GitHub to your local machine) by running the following on the command line: 16:35 ~/Projects$ git clone https://github.com/xeno-by/scala Cloning into 'scala'... @@ -76,7 +76,7 @@ which covers some of the things that will follow below. Then, _clone_ your repos Resolving deltas: 100% (182155/182155), done. This will create a local directory called `scala`, which contains a clone of your own copy of our repository. The changes that you make -in this directory can be propagated back to your copy hosted on github and, ultimately, pushed into Scala when your patch is ready. +in this directory can be propagated back to your copy hosted on GitHub and, ultimately, pushed into Scala when your patch is ready. ### Branch @@ -299,10 +299,10 @@ After development is finished, it's time to publish the code and submit your pat In a nutshell, this involves: 1. making sure that your code and commit messages are of high quality, -2. clicking a few buttons in the Github interface, -3. assigning one or more reviewers which will look through your pull request. +2. clicking a few buttons in the GitHub interface, +3. assigning one or more reviewers who will look through your pull request. - Let's go into each of these points in more detail. +Let's go into each of these points in more detail. ### Commit @@ -312,7 +312,7 @@ There are two things you should know here: 1. Commit messages are often the only way to understand the intentions of authors of code written a few years ago. Thus, writing a quality is of utmost importance. The more context you provide for the change you've introduced, the larger the chance that some future maintainer understand your intentions. Consult [the pull request policy](https://github.com/scala/scala/wiki/Pull-Request-Policy) for more information about the desired style of your commits. 2. Keeping Scala's git history clean is also important. Therefore we won't accept pull requests for bug fixes that have more than one commit. For features, it is okay to have several commits, but all tests need to pass after every single commit. To clean up your commit structure, you want to [rewrite history](http://git-scm.com/book/en/Git-Branching-Rebasing) using `git rebase` so that your commits are against the latest revision of `master`. -Once you are satisfied with your work, synced with `master` and cleaned up your commits you are ready to submit a patch to the central Scala repository. Before proceeding make sure you have pushed all of your local changes to your fork on Github. +Once you are satisfied with your work, synced with `master` and cleaned up your commits you are ready to submit a patch to the central Scala repository. Before proceeding make sure you have pushed all of your local changes to your fork on GitHub. 19:22 ~/Projects/scala/test (ticket/6725)$ git add ../src/compiler/scala/tools/reflect/MacroImplementations.scala 19:22 ~/Projects/scala/test (ticket/6725)$ git commit @@ -331,7 +331,7 @@ Once you are satisfied with your work, synced with `master` and cleaned up your ### Submit -Now, we must simply submit our proposed patch. Navigate to your branch in Github (for me it was `https://github.com/xeno-by/scala/tree/ticket/6725`) +Now, we must simply submit our proposed patch. Navigate to your branch in GitHub (for me it was `https://github.com/xeno-by/scala/tree/ticket/6725`) and click the pull request button to submit your patch as a pull request to Scala. If you've never submitted patches to Scala, you will need to sign the contributor license agreement, which [can be done online](http://typesafe.com/contribute/cla/scala) within a few minutes. From 50d50417d01e7eb834088ce5a3bf924b862eb26f Mon Sep 17 00:00:00 2001 From: Antoine Gourlay Date: Wed, 31 Jul 2013 23:46:24 +0200 Subject: [PATCH 0038/3075] fix links in hacker guide and various typos. --- contribute/bug-reporting-guide.md | 4 ++-- contribute/hacker-guide.md | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/contribute/bug-reporting-guide.md b/contribute/bug-reporting-guide.md index f04503f968..4160dcf438 100644 --- a/contribute/bug-reporting-guide.md +++ b/contribute/bug-reporting-guide.md @@ -45,7 +45,7 @@ If you have a code snippet that is resulting in bytecode which you believe is be * Keep in mind that the behavior you are witnessing could be intended. Good formal resources for verifying whether or not the language behavior is intended is either in the [Scala Improvement Proposal Documents](http://docs.scala-lang.org/sips/sip-list.html) or in the [Scala Language Specification](http://www.scala-lang.org/docu/files/ScalaReference.pdf). If in doubt, you may always ask on the [scala-internals mailing list](https://groups.google.com/forum/?fromgroups#!forum/scala-internals) or [stackoveflow](http://stackoverflow.com/questions/tagged/scala). -In general, if you find yourself stuck on any of these steps, asking on one of following Scala mailing lists can be helpful: +In general, if you find yourself stuck on any of these steps, asking on one of the following Scala mailing lists can be helpful: - For unexpected behavior use [scala-language](https://groups.google.com/forum/?fromgroups#!forum/scala-language), or [scala-user](https://groups.google.com/forum/?fromgroups#!forum/scala-user) mailing lists. - For compiler bugs use the [scala-internals](https://groups.google.com/forum/?fromgroups#!forum/scala-internals) mailing list. @@ -84,4 +84,4 @@ In the description of your issue, be as detailed as you can. Bug reports which h 2. The expected output. 3. The actual output, including the stacktrace. 4. Related discussion on the mailing lists, if applicable. - 4. If you have already looked into the issue provide interesting insights or proposals for fixing the issue. \ No newline at end of file + 4. If you have already looked into the issue provide interesting insights or proposals for fixing the issue. diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 28ea69bc3f..69ed05d25e 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -37,7 +37,7 @@ This is the list of language features/libraries along with their maintainers's f Since Martin is the person who submitted the string interpolation Scala Improvement Proposal and implemented this language feature for Scala 2.10.0, he might be interested in learning of new bugfixes to that feature. As alluded to earlier, one must also choose an appropriate mailing list. Typically, one would use the scala-internals mailing list, as it is devoted to discussions about the core internal design and implementation of the Scala system. However, since this issue has been discussed previously on the scala-user mailing list, -in this example, we post to the [the scala-user mailing list](http://groups.google.com/group/scala-user)about our issue. +in this example, we post to the [the scala-user mailing list](http://groups.google.com/group/scala-user) about our issue.
Posting to scala-user

@@ -143,7 +143,7 @@ Both Eclipse and IntelliJ IDEA have Scala plugins, which are known to work with [instructions for Intellij](https://github.com/scala/scala/blob/master/src/intellij/README). Both of those Scala plugins provide navigation, refactoring and error reporting functionality as well as integrated debugging. -There also exist lighter-weight editors such as Emacs, Sublime or jEdit which provide unparalleled are faster and much less memory/compute-intensive to run, while +There also exist lighter-weight editors such as Emacs, Sublime or jEdit which are faster and much less memory/compute-intensive to run, while lacking semantic services and debugging. To address this shortcoming, they can integrate with ENSIME, a helper program, which hosts a resident Scala compiler providing some of the features implemented in traditional IDEs. However despite having significantly matured over the last year, support for our particular code base is still being improved, and is not as mature as for Eclipse and IntelliJ. @@ -194,11 +194,11 @@ There are several areas that one could contribute to-- there is the Scala librar ##### The Scala Library -Contributing to the Scala standard library is about the same as working on one of your own libraries. Beyond the Scala collections hierarchy, there are no complex internals or architectures to have to worry about. Just make sure that you code in a "don't-repeat-yourself" (DRY) style, obeying the "boy scout principle" (i.e. make sure you've left something cleaner than you found it.) +Contributing to the Scala standard library is about the same as working on one of your own libraries. Beyond the Scala collections hierarchy, there are no complex internals or architectures to have to worry about. Just make sure that you code in a "don't-repeat-yourself" (DRY) style, obeying the "boy scout principle" (i.e. make sure you've left something cleaner than you found it). If documentation is necessary for some trait/class/object/method/etc in the Scala standard library, typically maintainers will include inline comments describing their design decisions or rationale for implementing things the way they have, if it is not straightforward. -If you intend on contributing to Scala collections, please make sure you're familiar with the design of the Scala collections library. It can be easy to put an implementation in the wrong location if you are unfamiliar with the collections architecture. There is an excellent and very detailed guide covering [the Architecture of Scala Collections](http://docs.scala-lang.org/overviews/core/architecture-of-scala-collections.html), as well as a larger more general [Scala collections Guide](http://docs.scala-lang.org/overviews/core/collections.html) covering the sequential portion of collections. For parallel collections, there also exists a detailed [Scala Parallel Collections Guide](http://docs.scala-lang.org/overviews/core/parallel-collections.html). (TODO double check these links!) +If you intend on contributing to Scala collections, please make sure you're familiar with the design of the Scala collections library. It can be easy to put an implementation in the wrong location if you are unfamiliar with the collections architecture. There is an excellent and very detailed guide covering [the Architecture of Scala Collections](http://docs.scala-lang.org/overviews/core/architecture-of-scala-collections.html), as well as a larger more general [Scala collections Guide](http://docs.scala-lang.org/overviews/collections/introduction.html) covering the sequential portion of collections. For parallel collections, there also exists a detailed [Scala Parallel Collections Guide](http://docs.scala-lang.org/overviews/parallel-collections/overview.html). ##### The Scala Compiler @@ -272,9 +272,9 @@ I have already written one test earlier, so that's a good start but not enough! Adding tests to the test suite is as easy as moving them to the appropriate directory: -* Code which should compile successfully, but doesn't need to be executed, needs to go into the [“pos” directory](https://github.com/scala/scala/tree/master/test/files/pos) -* Code which should not compile needs to go into the [“neg” directory](https://github.com/scala/scala/tree/master/test/files/neg) -* Code which should compile and get executed by the test suite needs to go into the [“run” directory](https://github.com/scala/scala/tree/master/test/files/run) +* Code which should compile successfully, but doesn't need to be executed, needs to go into the [“pos” directory](https://github.com/scala/scala/tree/master/test/files/pos). +* Code which should not compile needs to go into the [“neg” directory](https://github.com/scala/scala/tree/master/test/files/neg). +* Code which should compile and get executed by the test suite needs to go into the [“run” directory](https://github.com/scala/scala/tree/master/test/files/run). ### Verify From ac890ec4475ccac7b4cde69954e0325d770429f5 Mon Sep 17 00:00:00 2001 From: Ricky Elrod Date: Wed, 31 Jul 2013 21:44:19 -0400 Subject: [PATCH 0039/3075] Make hacker-guide valid. --- contribute/hacker-guide.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 69ed05d25e..5e22223278 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -39,9 +39,8 @@ Since Martin is the person who submitted the string interpolation Scala Improvem As alluded to earlier, one must also choose an appropriate mailing list. Typically, one would use the scala-internals mailing list, as it is devoted to discussions about the core internal design and implementation of the Scala system. However, since this issue has been discussed previously on the scala-user mailing list, in this example, we post to the [the scala-user mailing list](http://groups.google.com/group/scala-user) about our issue. -
Posting to scala-user
-
-
Response from Martin
+Posting to scala-user +Response from Martin Now that we have the approval of the feature's author, we can get to work! @@ -59,7 +58,7 @@ button in the top right corner of the page. This will create your own copy of ou If you're new to Git, don't be afraid of messing up-- there is no way you can corrupt our repository. -
Fork scala/scala
+Fork scala/scala ### Clone @@ -335,14 +334,14 @@ Now, we must simply submit our proposed patch. Navigate to your branch in GitHub and click the pull request button to submit your patch as a pull request to Scala. If you've never submitted patches to Scala, you will need to sign the contributor license agreement, which [can be done online](http://typesafe.com/contribute/cla/scala) within a few minutes. -
Submit a pull request
+Submit a pull request ### Review After the pull request has been submitted, you need to pick a reviewer (usually the person you've contacted in the beginning of your workflow) and be ready to elaborate and adjust your patch if necessary. In this example, we picked Martin, because we had such a nice chat on the mailing list: -
SAssign the reviewer
+SAssign the reviewer ## Merge From 38ef7cf6c68443939d834c4f5fe28bed129eb7e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 30 Sep 2013 14:30:04 +0200 Subject: [PATCH 0040/3075] Add hall of fame for July and August 2013. --- .../_posts/2013-08-01-scala-fame-2013-07.md | 119 ++++++++++++++++++ .../_posts/2013-09-01-scala-fame-2013-08.md | 98 +++++++++++++++ 2 files changed, 217 insertions(+) create mode 100644 contribute/scala-fame-data/_posts/2013-08-01-scala-fame-2013-07.md create mode 100644 contribute/scala-fame-data/_posts/2013-09-01-scala-fame-2013-08.md diff --git a/contribute/scala-fame-data/_posts/2013-08-01-scala-fame-2013-07.md b/contribute/scala-fame-data/_posts/2013-08-01-scala-fame-2013-07.md new file mode 100644 index 0000000000..b6670c42ce --- /dev/null +++ b/contribute/scala-fame-data/_posts/2013-08-01-scala-fame-2013-07.md @@ -0,0 +1,119 @@ +--- +layout: famearchive +title: Contributors of July 2013 +fame-year: 2013 +fame-month: 7 +fame-month-str: July +fame-categories: + - category: Typesafe + authors: + - username: gkossakowski + gravatar: https://0.gravatar.com/avatar/e608c8cb27858cc5aaf7d0c1e57958d7?d=https%3A%2F%2Fidenticons.github.com%2F8196e8d0f9ee7dfdfc7e11dbbfa30d77.png&s=60 + commits: 11 + linesAdded: 522 + linesDeleted: 311 + rank: 1 + newContributor: false + - username: adriaanm + gravatar: https://0.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?d=https%3A%2F%2Fidenticons.github.com%2Ff0d91e20ef53ace520f6ccbf8402319f.png&s=60 + commits: 9 + linesAdded: 1068 + linesDeleted: 11436 + rank: 2 + newContributor: false + - username: retronym + gravatar: https://0.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?d=https%3A%2F%2Fidenticons.github.com%2F75e4dffe50001cf8b96d3beecbe181be.png&s=60 + commits: 8 + linesAdded: 416 + linesDeleted: 134 + rank: 3 + newContributor: false + - username: paulp + gravatar: https://identicons.github.com/bf65417dcecc7f2b0006e1f5793b7143.png + commits: 2 + linesAdded: 46 + linesDeleted: 27 + rank: 4 + newContributor: false + - category: EPFL + authors: + - username: magarciaEPFL + gravatar: https://2.gravatar.com/avatar/94ff1d59d6e0a3a4ab10c80ab12bfeed?d=https%3A%2F%2Fidenticons.github.com%2F8b7440eff98d923640c99b5535429144.png&s=60 + commits: 12 + linesAdded: 1208 + linesDeleted: 1069 + rank: 1 + newContributor: false + - username: xeno-by + gravatar: https://2.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?d=https%3A%2F%2Fidenticons.github.com%2F6a5b1b05e953818962474e94b67d1cc2.png&s=60 + commits: 8 + linesAdded: 321 + linesDeleted: 95 + rank: 2 + newContributor: false + - username: VladUreche + gravatar: https://2.gravatar.com/avatar/5658ed1cea041577df360fd663c570fa?d=https%3A%2F%2Fidenticons.github.com%2Fa1ef2fed16f85a1af890467a80c30226.png&s=60 + commits: 2 + linesAdded: 104 + linesDeleted: 2 + rank: 3 + newContributor: false + - username: cvogt + gravatar: https://1.gravatar.com/avatar/669fb4eab529fba02f390051ddf3c8d3?d=https%3A%2F%2Fidenticons.github.com%2F78d9e7d7c73ac19ca8da9805762e5bb0.png&s=60 + commits: 1 + linesAdded: 19 + linesDeleted: 0 + rank: 4 + newContributor: false + - category: Community + authors: + - username: soc + gravatar: https://0.gravatar.com/avatar/6e4171314f4704b1e82aa4e5d9067e92?d=https%3A%2F%2Fidenticons.github.com%2F29f7ac3adbe1d3500c9404388aedcbfd.png&s=60 + commits: 19 + linesAdded: 2818 + linesDeleted: 4377 + rank: 1 + newContributor: false + - username: som-snytt + gravatar: https://2.gravatar.com/avatar/ec5b08d0fe94845ba49fd4a263c7d99d?d=https%3A%2F%2Fidenticons.github.com%2Fd292a902ebb73981efd65c9ef416046b.png&s=60 + commits: 16 + linesAdded: 1049 + linesDeleted: 553 + rank: 2 + newContributor: false + - username: densh + gravatar: https://0.gravatar.com/avatar/5ed274e115ec061d062d9c32a539cdc9?d=https%3A%2F%2Fidenticons.github.com%2Fcd3e73ab183ea35424f0bf59101a74e4.png&s=60 + commits: 9 + linesAdded: 2632 + linesDeleted: 178 + rank: 3 + newContributor: false + - username: folone + gravatar: https://2.gravatar.com/avatar/50e7e3f60b3507383d2b327857b66a62?d=https%3A%2F%2Fidenticons.github.com%2F6c2bcbccd23191b40f4932e2b8450681.png&s=60 + commits: 3 + linesAdded: 106 + linesDeleted: 261 + rank: 4 + newContributor: false + - username: xuwei-k + gravatar: https://2.gravatar.com/avatar/18d8b1bf73827b2a15e2bd3e75b4b34a?d=https%3A%2F%2Fidenticons.github.com%2Fdab0069935d770e6285411ed1f4398b9.png&s=60 + commits: 3 + linesAdded: 5 + linesDeleted: 5 + rank: 4 + newContributor: false + - username: gourlaysama + gravatar: https://2.gravatar.com/avatar/8acf3c87222f89b18786c8db60eb365d?d=https%3A%2F%2Fidenticons.github.com%2F76004d7b1fac3a2b262caa5e6bdf15c9.png&s=60 + commits: 2 + linesAdded: 67 + linesDeleted: 3 + rank: 5 + newContributor: false + - username: ScrapCodes + gravatar: https://0.gravatar.com/avatar/e9813bbbab2caa993bf7e2b2d60de894?d=https%3A%2F%2Fidenticons.github.com%2F38c660c74f82a216b75167debab770ed.png&s=60 + commits: 1 + linesAdded: 1 + linesDeleted: 1 + rank: 6 + newContributor: false +--- diff --git a/contribute/scala-fame-data/_posts/2013-09-01-scala-fame-2013-08.md b/contribute/scala-fame-data/_posts/2013-09-01-scala-fame-2013-08.md new file mode 100644 index 0000000000..c876e815d1 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2013-09-01-scala-fame-2013-08.md @@ -0,0 +1,98 @@ +--- +layout: famearchive +title: Contributors of August 2013 +fame-year: 2013 +fame-month: 8 +fame-month-str: August +fame-categories: + - category: Typesafe + authors: + - username: paulp + gravatar: https://identicons.github.com/bf65417dcecc7f2b0006e1f5793b7143.png + commits: 50 + linesAdded: 3703 + linesDeleted: 2269 + rank: 1 + newContributor: false + - username: retronym + gravatar: https://0.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?d=https%3A%2F%2Fidenticons.github.com%2F75e4dffe50001cf8b96d3beecbe181be.png&s=60 + commits: 30 + linesAdded: 990 + linesDeleted: 167 + rank: 2 + newContributor: false + - username: adriaanm + gravatar: https://0.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?d=https%3A%2F%2Fidenticons.github.com%2Ff0d91e20ef53ace520f6ccbf8402319f.png&s=60 + commits: 6 + linesAdded: 224 + linesDeleted: 11001 + rank: 3 + newContributor: false + - username: huitseeker + gravatar: https://0.gravatar.com/avatar/dc11aab8ab70b10a828b5ee4735183e8?d=https%3A%2F%2Fidenticons.github.com%2F0777acff7c9ab34562699e4e1d05affb.png&s=60 + commits: 2 + linesAdded: 6 + linesDeleted: 6 + rank: 4 + newContributor: false + - category: EPFL + authors: + - username: xeno-by + gravatar: https://2.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?d=https%3A%2F%2Fidenticons.github.com%2F6a5b1b05e953818962474e94b67d1cc2.png&s=60 + commits: 9 + linesAdded: 579 + linesDeleted: 419 + rank: 1 + newContributor: false + - username: magarciaEPFL + gravatar: https://2.gravatar.com/avatar/94ff1d59d6e0a3a4ab10c80ab12bfeed?d=https%3A%2F%2Fidenticons.github.com%2F8b7440eff98d923640c99b5535429144.png&s=60 + commits: 4 + linesAdded: 319 + linesDeleted: 105 + rank: 2 + newContributor: false + - category: Community + authors: + - username: densh + gravatar: https://0.gravatar.com/avatar/5ed274e115ec061d062d9c32a539cdc9?d=https%3A%2F%2Fidenticons.github.com%2Fcd3e73ab183ea35424f0bf59101a74e4.png&s=60 + commits: 19 + linesAdded: 687 + linesDeleted: 322 + rank: 1 + newContributor: false + - username: som-snytt + gravatar: https://2.gravatar.com/avatar/ec5b08d0fe94845ba49fd4a263c7d99d?d=https%3A%2F%2Fidenticons.github.com%2Fd292a902ebb73981efd65c9ef416046b.png&s=60 + commits: 12 + linesAdded: 455 + linesDeleted: 91 + rank: 2 + newContributor: false + - username: soc + gravatar: https://0.gravatar.com/avatar/6e4171314f4704b1e82aa4e5d9067e92?d=https%3A%2F%2Fidenticons.github.com%2F29f7ac3adbe1d3500c9404388aedcbfd.png&s=60 + commits: 4 + linesAdded: 64 + linesDeleted: 27 + rank: 3 + newContributor: false + - username: gourlaysama + gravatar: https://2.gravatar.com/avatar/8acf3c87222f89b18786c8db60eb365d?d=https%3A%2F%2Fidenticons.github.com%2F76004d7b1fac3a2b262caa5e6bdf15c9.png&s=60 + commits: 2 + linesAdded: 50 + linesDeleted: 9 + rank: 4 + newContributor: false + - username: ScrapCodes + gravatar: https://0.gravatar.com/avatar/e9813bbbab2caa993bf7e2b2d60de894?d=https%3A%2F%2Fidenticons.github.com%2F38c660c74f82a216b75167debab770ed.png&s=60 + commits: 1 + linesAdded: 3 + linesDeleted: 0 + rank: 5 + newContributor: false + - username: folone + gravatar: https://2.gravatar.com/avatar/50e7e3f60b3507383d2b327857b66a62?d=https%3A%2F%2Fidenticons.github.com%2F6c2bcbccd23191b40f4932e2b8450681.png&s=60 + commits: 1 + linesAdded: 55 + linesDeleted: 7 + rank: 5 + newContributor: false +--- From 1fad03554f97da791f28a74746dbb158f9109c02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Thu, 10 Oct 2013 11:17:43 +0200 Subject: [PATCH 0041/3075] Add hall of fame for 2013-09. --- .../_posts/2013-10-01-scala-fame-2013-09.md | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 contribute/scala-fame-data/_posts/2013-10-01-scala-fame-2013-09.md diff --git a/contribute/scala-fame-data/_posts/2013-10-01-scala-fame-2013-09.md b/contribute/scala-fame-data/_posts/2013-10-01-scala-fame-2013-09.md new file mode 100644 index 0000000000..23fa456fc0 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2013-10-01-scala-fame-2013-09.md @@ -0,0 +1,105 @@ +--- +layout: famearchive +title: Contributors of September 2013 +fame-year: 2013 +fame-month: 9 +fame-month-str: September +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://2.gravatar.com/avatar/5df8faf17a57ccab478a9b8056862fc3?d=https%3A%2F%2Fidenticons.github.com%2F75e4dffe50001cf8b96d3beecbe181be.png&s=60 + commits: 42 + linesAdded: 1459 + linesDeleted: 476 + rank: 1 + newContributor: false + - username: paulp + gravatar: https://identicons.github.com/bf65417dcecc7f2b0006e1f5793b7143.png + commits: 25 + linesAdded: 6603 + linesDeleted: 7419 + rank: 2 + newContributor: false + - username: huitseeker + gravatar: https://1.gravatar.com/avatar/dc11aab8ab70b10a828b5ee4735183e8?d=https%3A%2F%2Fidenticons.github.com%2F0777acff7c9ab34562699e4e1d05affb.png&s=60 + commits: 7 + linesAdded: 520 + linesDeleted: 536 + rank: 3 + newContributor: false + - username: gkossakowski + gravatar: https://0.gravatar.com/avatar/e608c8cb27858cc5aaf7d0c1e57958d7?d=https%3A%2F%2Fidenticons.github.com%2F8196e8d0f9ee7dfdfc7e11dbbfa30d77.png&s=60 + commits: 2 + linesAdded: 1443 + linesDeleted: 44 + rank: 4 + newContributor: false + - username: dragos + gravatar: https://2.gravatar.com/avatar/fbd384e9626d28d1648f023a5e22672f?d=https%3A%2F%2Fidenticons.github.com%2F6b660454242c937e501b88fd136132f8.png&s=60 + commits: 2 + linesAdded: 95 + linesDeleted: 13 + rank: 4 + newContributor: false + - username: jsuereth + gravatar: https://1.gravatar.com/avatar/5ed293320c06809a24812f56861201ad?d=https%3A%2F%2Fidenticons.github.com%2F11a5b5ef81cff76a0a1f3d042f635df3.png&s=60 + commits: 1 + linesAdded: 18 + linesDeleted: 37 + rank: 5 + newContributor: false + - username: adriaanm + gravatar: https://0.gravatar.com/avatar/d573d4b8a6bd9e2f41611d8d566c533e?d=https%3A%2F%2Fidenticons.github.com%2Ff0d91e20ef53ace520f6ccbf8402319f.png&s=60 + commits: 1 + linesAdded: 5 + linesDeleted: 5 + rank: 5 + newContributor: false + - category: EPFL + authors: + - username: xeno-by + gravatar: https://1.gravatar.com/avatar/69e339fd10a5ad804c45e22c819c67ad?d=https%3A%2F%2Fidenticons.github.com%2F6a5b1b05e953818962474e94b67d1cc2.png&s=60 + commits: 5 + linesAdded: 434 + linesDeleted: 153 + rank: 1 + newContributor: false + - username: sjrd + gravatar: https://1.gravatar.com/avatar/bc554c7355c8476dd63375b314b1bd97?d=https%3A%2F%2Fidenticons.github.com%2F7f7549008d59643d2ce9846ce0364947.png&s=60 + commits: 4 + linesAdded: 30 + linesDeleted: 9 + rank: 2 + newContributor: true + - category: Community + authors: + - username: densh + gravatar: https://1.gravatar.com/avatar/5ed274e115ec061d062d9c32a539cdc9?d=https%3A%2F%2Fidenticons.github.com%2Fcd3e73ab183ea35424f0bf59101a74e4.png&s=60 + commits: 20 + linesAdded: 1415 + linesDeleted: 594 + rank: 1 + newContributor: false + - username: som-snytt + gravatar: https://1.gravatar.com/avatar/ec5b08d0fe94845ba49fd4a263c7d99d?d=https%3A%2F%2Fidenticons.github.com%2Fd292a902ebb73981efd65c9ef416046b.png&s=60 + commits: 11 + linesAdded: 367 + linesDeleted: 106 + rank: 2 + newContributor: false + - username: Ichoran + gravatar: https://0.gravatar.com/avatar/3698349ad0b898d398a6573f4d1f867a?d=https%3A%2F%2Fidenticons.github.com%2Ffc12483537f3df99d480423de674e099.png&s=60 + commits: 3 + linesAdded: 75 + linesDeleted: 27 + rank: 3 + newContributor: true + - username: sschaef + gravatar: https://0.gravatar.com/avatar/dd80aab570fdb5f37e62de5422f44ed4?d=https%3A%2F%2Fidenticons.github.com%2Fb5a662bc30d97b377338f5dfb2b4cc66.png&s=60 + commits: 3 + linesAdded: 84 + linesDeleted: 139 + rank: 3 + newContributor: false +--- From 9b709e0b67f7e3b7594734b019f262fd1dcf6e15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20van=20Delft?= Date: Mon, 6 Jan 2014 14:49:42 +0100 Subject: [PATCH 0042/3075] Update hacker-guide.md Added two more Git learning resources --- contribute/hacker-guide.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 5e22223278..46d252984e 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -48,8 +48,11 @@ Now that we have the approval of the feature's author, we can get to work! Hacking Scala begins with creating a branch for your work item. To develop Scala we use [Git](http://git-scm.com/) and [GitHub](http://github.com/). This section of the guide provides a short walkthrough, but if you are new to Git, -it probably makes sense to familiarize yourself with Git first. We recommend the [Git Pro](http://git-scm.com/book/en/) -online book. +it probably makes sense to familiarize yourself with Git first. We recommend + +* the [Git Pro](http://git-scm.com/book/en/) online book. +* the help page on [Forking a Git Repository](https://help.github.com/articles/fork-a-repo). +* this great training tool [LearnGitBranching](http://pcottle.github.io/learnGitBranching/). One hour hands-on training helps more than 1000 hours reading. ### Fork From 6f80442e6ac4050d70ab6b06ed5d59ee8187637f Mon Sep 17 00:00:00 2001 From: George Leontiev Date: Wed, 25 Jun 2014 17:43:17 +0200 Subject: [PATCH 0043/3075] Update hacker guide: add more info, fix broken links. --- contribute/hacker-guide.md | 99 ++++++++++++++++++++++++++++++++------ 1 file changed, 83 insertions(+), 16 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 46d252984e..895d925f48 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -26,7 +26,7 @@ Sometimes it's appealing to hack alone and not to have to interact with others o this might not be the very best idea. There are people in the Scala community who have spent years accumulating knowledge about Scala libraries and internals. They might provide unique insights and, what's even better, direct assistance in their areas, so it is not only advantageous, but recommended to communicate with the community about your new patch. -Typically bug fixes and new features start out as an idea or an experiment posted on one of our mailing lists [our mailing lists]({{ site.baseurl }}/community/index.html#mailing_lists) to find out how people feel +Typically bug fixes and new features start out as an idea or an experiment posted on one of [our mailing lists]({{ site.baseurl }}/community/index.html#mailing_lists) to find out how people feel about things you want to implement. People proficient in certain areas of Scala usually monitor mailing lists, so you'll often get some help by simply posting a message. But the most efficient way to connect is to cc your message to one of the people responsible for maintaining the aspect of Scala which you wish to contribute to. @@ -67,7 +67,7 @@ If you're new to Git, don't be afraid of messing up-- there is no way you can co If everything went okay, you will be redirected to your own fork at `https://github.com/username/scala`, where `username` is your github user name. You might find it helpful to read [http://help.github.com/fork-a-repo/](http://help.github.com/fork-a-repo/), -which covers some of the things that will follow below. Then, _clone_ your repository (_i.e._ pull a copy from GitHub to your local machine) by running the following on the command line: +which covers some of the things that will follow below. Then, _clone_ your repository (i.e. pull a copy from GitHub to your local machine) by running the following on the command line: 16:35 ~/Projects$ git clone https://github.com/xeno-by/scala Cloning into 'scala'... @@ -86,7 +86,7 @@ Before you start making changes, always create your own branch. Never work on th the changes you plan on making. Use a prefix that describes the nature of your change. There are essentially two kinds of changes: bug fixes and new features. -* For bug fixes, use `issue/NNNN` for bug NNNN from the [Scala issue tracker](https://issues.scala-lang.org/). +* For bug fixes, use `issue/NNNN` or `ticket/NNNN` for bug NNNN from the [Scala issue tracker](https://issues.scala-lang.org/). * For new feature use `topic/XXX` for feature XXX. Use feature names that make sense in the context of the whole Scala project and not just to you personally. For example, if you work on diagrams in Scaladoc, use `topic/scaladoc-diagrams` instead of just `topic/diagrams` would be a good branch name. Since in our example, we're going to fix an existing bug [SI-6725](https://issues.scala-lang.org/browse/SI-6725), we'll create a branch named `ticket/6725`. @@ -98,8 +98,7 @@ If you are new to Git and branching, read the [Branching Chapter](http://git-scm ### Build -The next step after cloning your fork is setting up your machine to build Scala. The definitive guide on building Scala is located at -[https://github.com/scala/scala/blob/master/README.rst](https://github.com/scala/scala/blob/master/README.rst), but here's the summary: +The next step after cloning your fork is setting up your machine to build Scala. * It is recommended to use Java `1.6` (not `1.7` or `1.8`, because they might cause occasional glitches). * The build tool is `ant`. @@ -140,10 +139,8 @@ with your hardware). There's no single editor of choice for working with Scala sources, as there are trade-offs associated with each available tool. -Both Eclipse and IntelliJ IDEA have Scala plugins, which are known to work with our codebase. Here are -[instructions for Eclipse](https://github.com/scala/scala/blob/master/src/eclipse/README.md) and -[instructions for Intellij](https://github.com/scala/scala/blob/master/src/intellij/README). Both of those Scala plugins provide -navigation, refactoring and error reporting functionality as well as integrated debugging. +Both Eclipse and IntelliJ IDEA have Scala plugins, which are known to work with our codebase. +Both of those Scala plugins provide navigation, refactoring and error reporting functionality as well as integrated debugging. There also exist lighter-weight editors such as Emacs, Sublime or jEdit which are faster and much less memory/compute-intensive to run, while lacking semantic services and debugging. To address this shortcoming, they can integrate with ENSIME, @@ -185,10 +182,33 @@ Here are also some tips & tricks that have proven useful in Scala development: just that trait, but it might also be necessary to recompile its users. The `ant` tool is not smart enough to do that, which might lead to very strange errors. Full-rebuilds fix the problem. Fortunately that's rarely necessary, because full-rebuilds take a lot of time-- the same 8-30 minutes as mentioned above. * Even on solid state drives packaging Scala distribution (i.e. creating jars from class files) is a non-trivial task. To save time here, - some people in our team do `ant quick.comp` instead of `ant` and then create custom scripts to launch Scala from `build/quick/classes`. + some people in our team do `ant quick.comp` instead of `ant` and then create custom scripts ([here](https://github.com/adriaanm/binfu/blob/master/scafu.sh) are some examples to get you strarted) to launch Scala from `build/quick/classes`. * Don't underestimate the power of `print`. When starting with Scala, I spent a lot of time in the debugger trying to figure out how things work. However later I found out that print-based debugging is often more effective than jumping around. While it might be obvious - to some, I'd like to explicitly mention that it's also useful to print stack traces to understand the flow of execution. + to some, I'd like to explicitly mention that it's also useful to print stack traces to understand the flow of execution. When working with `Trees`, you might want to use `showRaw` to get the `AST` representation. +* You can publish your newly-built scala version locally to use it from sbt. Here's how: + + $ ant publish-local-opt -Dmaven.version.suffix="-test" + $ sbt + [info] Set current project to test (in build file:/Users/georgii/workspace/test/) + > set resolvers += Resolver.mavenLocal + [info] Defining *:resolvers + [info] The new value will be used by *:externalResolvers + [info] Reapplying settings... + [info] Set current project to test (in build file:/Users/georgii/workspace/test/) + > ++2.12.0-test + [info] Setting version to 2.12.0-test + [info] Set current project to test (in build file:/Users/georgii/workspace/test/) + > console + [info] Starting scala interpreter... + [info] + Welcome to Scala version 2.12.0-20140623-155543-8bdacad317 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_51). + Type in expressions to have them evaluated. + Type :help for more information. + + scala> + +* Adding a macro to the `Predef` is a pretty involved task. For the reason of bootstrapping, you cannot just throw a macro into it. There is a more involved process here. You might want to follow the way `StringContext.f` itself is added. In short, you need to define your macro under `src/compiler/scala/tools/reflect/` and provide no implementation in `Predef` (`def fn = macro ???`). Now you want to set up the wiring. Add the name of your macro to `src/reflect/scala/reflect/internal/StdNames.scala`, add the needed links to it to `src/reflect/scala/reflect/internal/Definitions.scala`, and finally specify the bindings in `src/compiler/scala/tools/reflect/FastTrack.scala`. If that explanation does not sound very clear, [here's](https://github.com/folone/scala/commit/59536ea833ca16c985339727baed5d70e577b0fe) an example of adding a macro. ### Documentation @@ -196,7 +216,7 @@ There are several areas that one could contribute to-- there is the Scala librar ##### The Scala Library -Contributing to the Scala standard library is about the same as working on one of your own libraries. Beyond the Scala collections hierarchy, there are no complex internals or architectures to have to worry about. Just make sure that you code in a "don't-repeat-yourself" (DRY) style, obeying the "boy scout principle" (i.e. make sure you've left something cleaner than you found it). +Contributing to the Scala standard library is about the same as working on one of your own libraries. Beyond the Scala collections hierarchy, there are no complex internals or architectures to have to worry about. Just make sure that you code in a "don't-repeat-yourself" (DRY) style, obeying the "boy scout principle" (i.e. make sure you've left the code cleaner than you found it). If documentation is necessary for some trait/class/object/method/etc in the Scala standard library, typically maintainers will include inline comments describing their design decisions or rationale for implementing things the way they have, if it is not straightforward. @@ -206,7 +226,7 @@ If you intend on contributing to Scala collections, please make sure you're fami Documentation about the internal workings of the Scala compiler is scarce, and most of the knowledge is passed around by email (scala-internals mailing list), ticket, or word of mouth. However the situation is steadily improving. Here are the resources that might help: -* [Compiler internals videos by Martin Odersky](TODO) are quite dated, but still very useful. In this three-video +* [Compiler internals videos by Martin Odersky](http://www.scala-lang.org/old/node/598.html) are quite dated, but still very useful. In this three-video series Martin explains the general architecture of the compiler, and the basics of the front-end, which has recently become Scala reflection API. * [Reflection documentation](http://docs.scala-lang.org/overviews/reflection/overview.html) describes fundamental data structures (like `Tree`s, `Symbol`s, and `Types`) that are used to represent Scala programs and operations defined on then. Since much of the compiler has been factored out and made accessible via the Reflection API, all of the fundamentals needed for reflection are the same for the compiler. @@ -274,9 +294,56 @@ I have already written one test earlier, so that's a good start but not enough! Adding tests to the test suite is as easy as moving them to the appropriate directory: -* Code which should compile successfully, but doesn't need to be executed, needs to go into the [“pos” directory](https://github.com/scala/scala/tree/master/test/files/pos). -* Code which should not compile needs to go into the [“neg” directory](https://github.com/scala/scala/tree/master/test/files/neg). -* Code which should compile and get executed by the test suite needs to go into the [“run” directory](https://github.com/scala/scala/tree/master/test/files/run). +* Code which should compile successfully, but doesn't need to be executed, needs to go into the [“pos” directory](https://github.com/scala/scala/tree/2.12.x/test/files/pos). +* Code which should not compile needs to go into the [“neg” directory](https://github.com/scala/scala/tree/2.12.x/test/files/neg). +* Code which should compile and get executed by the test suite needs to go into the [“run” directory](https://github.com/scala/scala/tree/2.12.x/test/files/run) and have a corresponding `.check` file with the expected output. You will get test failures if the content of a `.check` file is different from what the test produces while running. If the change in the output is an expected product of your work, you might not want to change the `.check` file by hand. To make partest change the `.check` file, run it with a `--update-check` flag, like so `./test/partest --update-check path/to/test.scala`. For more information on partest, please refer to its [documentation](http://docs.scala-lang.org/tutorials/partest-guide.html). +* Everything that can be unit-tested should go to ["junit" directory](https://github.com/scala/scala/tree/2.12.x/test/junit) +* Property-based tests go to the ["scalacheck" directory](https://github.com/scala/scala/tree/2.12.x/test/files/scalacheck) + +Here are some more testing tips: + +* If you have several tests, and want a tool for only running tests that conform to some regular expression, you can use `partest-ack` in the `tools` directory: `./tools/partest-ack "dottype"` +* If your tests fail with an like: + + test.bc: + [echo] Checking backward binary compatibility for scala-library (against 2.11.0) + [mima] Found 2 binary incompatibiities + [mima] ================================ + [mima] * synthetic method + [mima] scala$package$Class$method(java.lang.String)Unit in trait + [mima] scala.package.Class does not have a correspondent in old version + [mima] * synthetic method + [mima] scala$package$AnotherClass$anotherMethod(java.lang.String)Unit in trait + [mima] scala.package.AnotherClass does not have a correspondent in old version + [mima] Generated filter config definition + [mima] ================================== + [mima] + [mima] filter { + [mima] problems=[ + [mima] { + [mima] matchName="scala.package.Class$method" + [mima] problemName=MissingMethodProblem + [mima] }, + [mima] { + [mima] matchName="scala.package.AnotherClass$anotherMethod" + [mima] problemName=MissingMethodProblem + [mima] } + [mima] ] + [mima] } + [mima] + + BUILD FAILED + /localhome/jenkins/c/workspace/pr-scala-test/scala/build.xml:1530: The following error occurred while executing this line: + /localhome/jenkins/c/workspace/pr-scala-test/scala/build-ant-macros.xml:791: The following error occurred while executing this line: + /localhome/jenkins/c/workspace/pr-scala-test/scala/build-ant-macros.xml:773: Java returned: 2 + + Total time: 6 minutes 46 seconds + Build step 'Execute shell' marked build as failure + Archiving artifacts + Notifying upstream projects of job completion + Finished: FAILURE + +This means your change is backward or forward binary incompatible with the specified version (the check is performed by the [migration manager](https://github.com/typesafehub/migration-manager)). The error message is actually saying what you need to add to `bincompat-backward.whitelist.conf` or `bincompat-forward.whitelist.conf` to make the error go away. If you are getting this on an internal/experimental api, it should be safe to add suggested sections to the config. Otherwise, you might want to target a newer version of scala for this change. ### Verify From a076f43769050b80646fb196a9b109e6ed97228f Mon Sep 17 00:00:00 2001 From: George Leontiev Date: Thu, 26 Jun 2014 10:44:54 +0200 Subject: [PATCH 0044/3075] Address the feedback. --- contribute/hacker-guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contribute/hacker-guide.md b/contribute/hacker-guide.md index 895d925f48..08f5d40c09 100644 --- a/contribute/hacker-guide.md +++ b/contribute/hacker-guide.md @@ -208,7 +208,7 @@ Here are also some tips & tricks that have proven useful in Scala development: scala> -* Adding a macro to the `Predef` is a pretty involved task. For the reason of bootstrapping, you cannot just throw a macro into it. There is a more involved process here. You might want to follow the way `StringContext.f` itself is added. In short, you need to define your macro under `src/compiler/scala/tools/reflect/` and provide no implementation in `Predef` (`def fn = macro ???`). Now you want to set up the wiring. Add the name of your macro to `src/reflect/scala/reflect/internal/StdNames.scala`, add the needed links to it to `src/reflect/scala/reflect/internal/Definitions.scala`, and finally specify the bindings in `src/compiler/scala/tools/reflect/FastTrack.scala`. If that explanation does not sound very clear, [here's](https://github.com/folone/scala/commit/59536ea833ca16c985339727baed5d70e577b0fe) an example of adding a macro. +* Adding a macro to the `Predef` object is a pretty involved task. Due to bootstrapping, you cannot just throw a macro into it. For this reason, the process is more involved. You might want to follow the way `StringContext.f` itself is added. In short, you need to define your macro under `src/compiler/scala/tools/reflect/` and provide no implementation in `Predef` (`def fn = macro ???`). Now you have to set up the wiring. Add the name of your macro to `src/reflect/scala/reflect/internal/StdNames.scala`, add the needed links to it to `src/reflect/scala/reflect/internal/Definitions.scala`, and finally specify the bindings in `src/compiler/scala/tools/reflect/FastTrack.scala`. [Here's](https://github.com/folone/scala/commit/59536ea833ca16c985339727baed5d70e577b0fe) an example of adding a macro. ### Documentation @@ -303,7 +303,7 @@ Adding tests to the test suite is as easy as moving them to the appropriate dire Here are some more testing tips: * If you have several tests, and want a tool for only running tests that conform to some regular expression, you can use `partest-ack` in the `tools` directory: `./tools/partest-ack "dottype"` -* If your tests fail with an like: +* If your tests fail in the following way: test.bc: [echo] Checking backward binary compatibility for scala-library (against 2.11.0) From 8f63cd0ebdf244c5051357d3781d985b54d126da Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Mon, 7 Jul 2014 20:28:10 +0200 Subject: [PATCH 0045/3075] Fix more references to spec --- contribute/bug-reporting-guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/bug-reporting-guide.md b/contribute/bug-reporting-guide.md index 4160dcf438..960f40b704 100644 --- a/contribute/bug-reporting-guide.md +++ b/contribute/bug-reporting-guide.md @@ -43,7 +43,7 @@ If you have a code snippet that is resulting in bytecode which you believe is be 5. If you want to file an improvement in the issue tracker please discuss it first on one of the mailing lists. They offer much bigger audience than issue tracker. The latter is not suitable for long discussions. -* Keep in mind that the behavior you are witnessing could be intended. Good formal resources for verifying whether or not the language behavior is intended is either in the [Scala Improvement Proposal Documents](http://docs.scala-lang.org/sips/sip-list.html) or in the [Scala Language Specification](http://www.scala-lang.org/docu/files/ScalaReference.pdf). If in doubt, you may always ask on the [scala-internals mailing list](https://groups.google.com/forum/?fromgroups#!forum/scala-internals) or [stackoveflow](http://stackoverflow.com/questions/tagged/scala). +* Keep in mind that the behavior you are witnessing could be intended. Good formal resources for verifying whether or not the language behavior is intended is either in the [Scala Improvement Proposal Documents](http://docs.scala-lang.org/sips/sip-list.html) or in the [Scala Language Specification](http://www.scala-lang.org/files/archive/spec/2.11/). If in doubt, you may always ask on the [scala-internals mailing list](https://groups.google.com/forum/?fromgroups#!forum/scala-internals) or [stackoveflow](http://stackoverflow.com/questions/tagged/scala). In general, if you find yourself stuck on any of these steps, asking on one of the following Scala mailing lists can be helpful: From afc73aa06baf7b9204c11edd946b02e82b74fcaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Doeraene?= Date: Mon, 29 Sep 2014 10:30:37 +0200 Subject: [PATCH 0046/3075] Hall of fame Auguest 2014. --- .../_posts/2014-09-01-scala-fame-2014-08.md | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 contribute/scala-fame-data/_posts/2014-09-01-scala-fame-2014-08.md diff --git a/contribute/scala-fame-data/_posts/2014-09-01-scala-fame-2014-08.md b/contribute/scala-fame-data/_posts/2014-09-01-scala-fame-2014-08.md new file mode 100644 index 0000000000..1393e01705 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2014-09-01-scala-fame-2014-08.md @@ -0,0 +1,63 @@ +--- +layout: famearchive +title: Contributors of August 2014 +fame-year: 2014 +fame-month: 8 +fame-month-str: August +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 + commits: 3 + linesAdded: 57 + linesDeleted: 4 + rank: 1 + newContributor: false + - username: adriaanm + gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 + commits: 2 + linesAdded: 57 + linesDeleted: 42 + rank: 2 + newContributor: false + - category: EPFL + authors: + - username: lrytz + gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 + commits: 21 + linesAdded: 3764 + linesDeleted: 2122 + rank: 1 + newContributor: false + - category: Community + authors: + - username: gourlaysama + gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 + commits: 10 + linesAdded: 171 + linesDeleted: 7680 + rank: 1 + newContributor: false + - username: som-snytt + gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 + commits: 10 + linesAdded: 917 + linesDeleted: 543 + rank: 1 + newContributor: false + - username: dgruntz + gravatar: https://avatars3.githubusercontent.com/u/1516800?v=2&s=60 + commits: 1 + linesAdded: 18 + linesDeleted: 18 + rank: 2 + newContributor: false + - username: Ichoran + gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 + commits: 1 + linesAdded: 26 + linesDeleted: 27 + rank: 2 + newContributor: false +--- From d4630ea3257b7740c390f5d728b6d2fd012f7fc1 Mon Sep 17 00:00:00 2001 From: Fabien Salvi Date: Fri, 24 Oct 2014 16:36:48 +0200 Subject: [PATCH 0047/3075] Add 2014 scala-fame data --- .../_posts/2014-02-01-scala-fame-2014-01.md | 147 ++++++++++++++++++ .../_posts/2014-03-01-scala-fame-2014-02.md | 133 ++++++++++++++++ .../_posts/2014-04-01-scala-fame-2014-03.md | 112 +++++++++++++ .../_posts/2014-05-01-scala-fame-2014-04.md | 91 +++++++++++ .../_posts/2014-06-01-scala-fame-2014-05.md | 112 +++++++++++++ .../_posts/2014-07-01-scala-fame-2014-06.md | 98 ++++++++++++ .../_posts/2014-08-01-scala-fame-2014-07.md | 98 ++++++++++++ .../_posts/2014-09-01-scala-fame-2014-08.md | 7 + .../_posts/2014-10-01-scala-fame-2014-09.md | 84 ++++++++++ 9 files changed, 882 insertions(+) create mode 100644 contribute/scala-fame-data/_posts/2014-02-01-scala-fame-2014-01.md create mode 100644 contribute/scala-fame-data/_posts/2014-03-01-scala-fame-2014-02.md create mode 100644 contribute/scala-fame-data/_posts/2014-04-01-scala-fame-2014-03.md create mode 100644 contribute/scala-fame-data/_posts/2014-05-01-scala-fame-2014-04.md create mode 100644 contribute/scala-fame-data/_posts/2014-06-01-scala-fame-2014-05.md create mode 100644 contribute/scala-fame-data/_posts/2014-07-01-scala-fame-2014-06.md create mode 100644 contribute/scala-fame-data/_posts/2014-08-01-scala-fame-2014-07.md create mode 100644 contribute/scala-fame-data/_posts/2014-10-01-scala-fame-2014-09.md diff --git a/contribute/scala-fame-data/_posts/2014-02-01-scala-fame-2014-01.md b/contribute/scala-fame-data/_posts/2014-02-01-scala-fame-2014-01.md new file mode 100644 index 0000000000..ab8e808036 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2014-02-01-scala-fame-2014-01.md @@ -0,0 +1,147 @@ +--- +layout: famearchive +title: Contributors of January 2014 +fame-year: 2014 +fame-month: 1 +fame-month-str: January +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 + commits: 37 + linesAdded: 2000 + linesDeleted: 2487 + rank: 1 + newContributor: false + - username: adriaanm + gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 + commits: 8 + linesAdded: 311 + linesDeleted: 175 + rank: 2 + newContributor: false + - username: gkossakowski + gravatar: https://avatars0.githubusercontent.com/u/4217?v=2&s=60 + commits: 3 + linesAdded: 15 + linesDeleted: 5 + rank: 3 + newContributor: false + - username: huitseeker + gravatar: https://avatars2.githubusercontent.com/u/4142?v=2&s=60 + commits: 2 + linesAdded: 81 + linesDeleted: 79 + rank: 4 + newContributor: false + - username: paulp + gravatar: https://avatars2.githubusercontent.com/u/9135?v=2&s=60 + commits: 2 + linesAdded: 7 + linesDeleted: 5 + rank: 4 + newContributor: false + - category: EPFL + authors: + - username: xeno-by + gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 + commits: 75 + linesAdded: 8908 + linesDeleted: 6023 + rank: 1 + newContributor: false + - category: Community + authors: + - username: densh + gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 + commits: 16 + linesAdded: 722 + linesDeleted: 295 + rank: 1 + newContributor: false + - username: Ichoran + gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 + commits: 10 + linesAdded: 315 + linesDeleted: 103 + rank: 2 + newContributor: false + - username: som-snytt + gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 + commits: 9 + linesAdded: 646 + linesDeleted: 201 + rank: 3 + newContributor: false + - username: VladimirNik + gravatar: https://avatars2.githubusercontent.com/u/2835001?v=2&s=60 + commits: 7 + linesAdded: 1729 + linesDeleted: 350 + rank: 4 + newContributor: false + - username: rklaehn + gravatar: https://avatars0.githubusercontent.com/u/248257?v=2&s=60 + commits: 6 + linesAdded: 1288 + linesDeleted: 39 + rank: 5 + newContributor: false + - username: gourlaysama + gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 + commits: 3 + linesAdded: 37 + linesDeleted: 7 + rank: 6 + newContributor: false + - username: cunei + gravatar: https://avatars2.githubusercontent.com/u/686260?v=2&s=60 + commits: 2 + linesAdded: 42 + linesDeleted: 12 + rank: 7 + newContributor: false + - username: Blaisorblade + gravatar: https://avatars2.githubusercontent.com/u/289960?v=2&s=60 + commits: 2 + linesAdded: 51 + linesDeleted: 33 + rank: 7 + newContributor: false + - username: havocp + gravatar: https://avatars2.githubusercontent.com/u/218689?v=2&s=60 + commits: 1 + linesAdded: 38 + linesDeleted: 2 + rank: 8 + newContributor: false + - username: clhodapp + gravatar: https://avatars0.githubusercontent.com/u/108633?v=2&s=60 + commits: 1 + linesAdded: 22 + linesDeleted: 0 + rank: 8 + newContributor: false + - username: rjolly + gravatar: https://avatars3.githubusercontent.com/u/128610?v=2&s=60 + commits: 1 + linesAdded: 45 + linesDeleted: 38 + rank: 8 + newContributor: false + - username: xuwei-k + gravatar: https://avatars3.githubusercontent.com/u/389787?v=2&s=60 + commits: 1 + linesAdded: 1 + linesDeleted: 1 + rank: 8 + newContributor: false + - username: dotta + gravatar: https://avatars2.githubusercontent.com/u/703748?v=2&s=60 + commits: 1 + linesAdded: 67 + linesDeleted: 67 + rank: 8 + newContributor: false +--- diff --git a/contribute/scala-fame-data/_posts/2014-03-01-scala-fame-2014-02.md b/contribute/scala-fame-data/_posts/2014-03-01-scala-fame-2014-02.md new file mode 100644 index 0000000000..065ab45d13 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2014-03-01-scala-fame-2014-02.md @@ -0,0 +1,133 @@ +--- +layout: famearchive +title: Contributors of February 2014 +fame-year: 2014 +fame-month: 2 +fame-month-str: February +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 + commits: 47 + linesAdded: 1533 + linesDeleted: 1032 + rank: 1 + newContributor: false + - username: adriaanm + gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 + commits: 25 + linesAdded: 1043 + linesDeleted: 491 + rank: 2 + newContributor: false + - username: gkossakowski + gravatar: https://avatars0.githubusercontent.com/u/4217?v=2&s=60 + commits: 4 + linesAdded: 1867 + linesDeleted: 1747 + rank: 3 + newContributor: false + - username: paulp + gravatar: https://avatars2.githubusercontent.com/u/9135?v=2&s=60 + commits: 3 + linesAdded: 427 + linesDeleted: 15 + rank: 4 + newContributor: false + - username: dragos + gravatar: https://avatars2.githubusercontent.com/u/133742?v=2&s=60 + commits: 1 + linesAdded: 12 + linesDeleted: 3 + rank: 5 + newContributor: false + - category: EPFL + authors: + - username: xeno-by + gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 + commits: 47 + linesAdded: 3989 + linesDeleted: 1545 + rank: 1 + newContributor: false + - username: lrytz + gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 + commits: 1 + linesAdded: 18 + linesDeleted: 13 + rank: 2 + newContributor: false + - category: Community + authors: + - username: densh + gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 + commits: 23 + linesAdded: 1166 + linesDeleted: 515 + rank: 1 + newContributor: false + - username: VladimirNik + gravatar: https://avatars2.githubusercontent.com/u/2835001?v=2&s=60 + commits: 10 + linesAdded: 2647 + linesDeleted: 2416 + rank: 2 + newContributor: false + - username: som-snytt + gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 + commits: 9 + linesAdded: 662 + linesDeleted: 339 + rank: 3 + newContributor: false + - username: Ichoran + gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 + commits: 8 + linesAdded: 277 + linesDeleted: 75 + rank: 4 + newContributor: false + - username: pavelpavlov + gravatar: https://avatars0.githubusercontent.com/u/1330451?v=2&s=60 + commits: 3 + linesAdded: 44 + linesDeleted: 54 + rank: 5 + newContributor: false + - username: Blaisorblade + gravatar: https://avatars2.githubusercontent.com/u/289960?v=2&s=60 + commits: 3 + linesAdded: 6 + linesDeleted: 5 + rank: 5 + newContributor: false + - username: soc + gravatar: https://avatars0.githubusercontent.com/u/42493?v=2&s=60 + commits: 3 + linesAdded: 476 + linesDeleted: 338 + rank: 5 + newContributor: false + - username: gourlaysama + gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 + commits: 2 + linesAdded: 7 + linesDeleted: 7 + rank: 6 + newContributor: false + - username: greenrd + gravatar: https://avatars1.githubusercontent.com/u/164965?v=2&s=60 + commits: 1 + linesAdded: 2 + linesDeleted: 3 + rank: 7 + newContributor: false + - username: clhodapp + gravatar: https://avatars0.githubusercontent.com/u/108633?v=2&s=60 + commits: 1 + linesAdded: 228 + linesDeleted: 0 + rank: 7 + newContributor: false +--- diff --git a/contribute/scala-fame-data/_posts/2014-04-01-scala-fame-2014-03.md b/contribute/scala-fame-data/_posts/2014-04-01-scala-fame-2014-03.md new file mode 100644 index 0000000000..954a870612 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2014-04-01-scala-fame-2014-03.md @@ -0,0 +1,112 @@ +--- +layout: famearchive +title: Contributors of March 2014 +fame-year: 2014 +fame-month: 3 +fame-month-str: March +fame-categories: + - category: Typesafe + authors: + - username: adriaanm + gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 + commits: 79 + linesAdded: 24547 + linesDeleted: 24999 + rank: 1 + newContributor: false + - username: retronym + gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 + commits: 21 + linesAdded: 622 + linesDeleted: 101 + rank: 2 + newContributor: false + - username: gkossakowski + gravatar: https://avatars0.githubusercontent.com/u/4217?v=2&s=60 + commits: 3 + linesAdded: 236 + linesDeleted: 6 + rank: 3 + newContributor: false + - username: huitseeker + gravatar: https://avatars2.githubusercontent.com/u/4142?v=2&s=60 + commits: 2 + linesAdded: 4 + linesDeleted: 2 + rank: 4 + newContributor: false + - username: szeiger + gravatar: https://avatars3.githubusercontent.com/u/54262?v=2&s=60 + commits: 1 + linesAdded: 8 + linesDeleted: 1 + rank: 5 + newContributor: false + - username: viktorklang + gravatar: https://avatars0.githubusercontent.com/u/10871?v=2&s=60 + commits: 1 + linesAdded: 7 + linesDeleted: 2 + rank: 5 + newContributor: false + - username: paulp + gravatar: https://avatars2.githubusercontent.com/u/9135?v=2&s=60 + commits: 1 + linesAdded: 20 + linesDeleted: 3 + rank: 5 + newContributor: false + - category: EPFL + authors: + - username: xeno-by + gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 + commits: 10 + linesAdded: 379 + linesDeleted: 76 + rank: 1 + newContributor: false + - category: Community + authors: + - username: densh + gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 + commits: 13 + linesAdded: 589 + linesDeleted: 115 + rank: 1 + newContributor: false + - username: som-snytt + gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 + commits: 4 + linesAdded: 31 + linesDeleted: 23 + rank: 2 + newContributor: false + - username: VladimirNik + gravatar: https://avatars2.githubusercontent.com/u/2835001?v=2&s=60 + commits: 2 + linesAdded: 1778 + linesDeleted: 1441 + rank: 3 + newContributor: false + - username: mkubala + gravatar: https://avatars0.githubusercontent.com/u/328844?v=2&s=60 + commits: 1 + linesAdded: 247 + linesDeleted: 53 + rank: 4 + newContributor: false + - username: puffnfresh + gravatar: https://avatars1.githubusercontent.com/u/37715?v=2&s=60 + commits: 1 + linesAdded: 0 + linesDeleted: 1 + rank: 4 + newContributor: false + - username: iainmcgin + gravatar: https://avatars0.githubusercontent.com/u/309153?v=2&s=60 + commits: 1 + linesAdded: 20 + linesDeleted: 19 + rank: 4 + newContributor: false +--- diff --git a/contribute/scala-fame-data/_posts/2014-05-01-scala-fame-2014-04.md b/contribute/scala-fame-data/_posts/2014-05-01-scala-fame-2014-04.md new file mode 100644 index 0000000000..66c6819f17 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2014-05-01-scala-fame-2014-04.md @@ -0,0 +1,91 @@ +--- +layout: famearchive +title: Contributors of April 2014 +fame-year: 2014 +fame-month: 4 +fame-month-str: April +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 + commits: 9 + linesAdded: 177 + linesDeleted: 34 + rank: 1 + newContributor: false + - username: huitseeker + gravatar: https://avatars2.githubusercontent.com/u/4142?v=2&s=60 + commits: 1 + linesAdded: 16 + linesDeleted: 1 + rank: 2 + newContributor: false + - username: gkossakowski + gravatar: https://avatars0.githubusercontent.com/u/4217?v=2&s=60 + commits: 1 + linesAdded: 10 + linesDeleted: 3 + rank: 2 + newContributor: false + - username: adriaanm + gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 + commits: 1 + linesAdded: 34 + linesDeleted: 2 + rank: 2 + newContributor: false + - category: EPFL + authors: + - username: lrytz + gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 + commits: 2 + linesAdded: 202 + linesDeleted: 75 + rank: 1 + newContributor: false + - username: VladUreche + gravatar: https://avatars0.githubusercontent.com/u/428706?v=2&s=60 + commits: 1 + linesAdded: 24 + linesDeleted: 3 + rank: 2 + newContributor: false + - username: xeno-by + gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 + commits: 1 + linesAdded: 12 + linesDeleted: 1 + rank: 2 + newContributor: false + - category: Community + authors: + - username: gourlaysama + gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 + commits: 3 + linesAdded: 51 + linesDeleted: 5 + rank: 1 + newContributor: false + - username: som-snytt + gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 + commits: 2 + linesAdded: 110 + linesDeleted: 51 + rank: 2 + newContributor: false + - username: lefou + gravatar: https://avatars2.githubusercontent.com/u/1321393?v=2&s=60 + commits: 1 + linesAdded: 45 + linesDeleted: 8 + rank: 3 + newContributor: false + - username: densh + gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 + commits: 1 + linesAdded: 4 + linesDeleted: 5 + rank: 3 + newContributor: false +--- diff --git a/contribute/scala-fame-data/_posts/2014-06-01-scala-fame-2014-05.md b/contribute/scala-fame-data/_posts/2014-06-01-scala-fame-2014-05.md new file mode 100644 index 0000000000..f9191afb17 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2014-06-01-scala-fame-2014-05.md @@ -0,0 +1,112 @@ +--- +layout: famearchive +title: Contributors of May 2014 +fame-year: 2014 +fame-month: 5 +fame-month-str: May +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 + commits: 32 + linesAdded: 951 + linesDeleted: 136 + rank: 1 + newContributor: false + - username: adriaanm + gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 + commits: 9 + linesAdded: 21 + linesDeleted: 70 + rank: 2 + newContributor: false + - username: gkossakowski + gravatar: https://avatars0.githubusercontent.com/u/4217?v=2&s=60 + commits: 3 + linesAdded: 13 + linesDeleted: 18 + rank: 3 + newContributor: false + - category: EPFL + authors: + - username: lrytz + gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 + commits: 23 + linesAdded: 6048 + linesDeleted: 2325 + rank: 1 + newContributor: false + - username: xeno-by + gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 + commits: 3 + linesAdded: 93 + linesDeleted: 3 + rank: 2 + newContributor: false + - category: Community + authors: + - username: som-snytt + gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 + commits: 12 + linesAdded: 442 + linesDeleted: 238 + rank: 1 + newContributor: false + - username: lefou + gravatar: https://avatars2.githubusercontent.com/u/1321393?v=2&s=60 + commits: 3 + linesAdded: 14 + linesDeleted: 24 + rank: 2 + newContributor: false + - username: tvierling + gravatar: https://avatars3.githubusercontent.com/u/397857?v=2&s=60 + commits: 2 + linesAdded: 35 + linesDeleted: 11 + rank: 3 + newContributor: true + - username: clhodapp + gravatar: https://avatars0.githubusercontent.com/u/108633?v=2&s=60 + commits: 2 + linesAdded: 98 + linesDeleted: 51 + rank: 3 + newContributor: false + - username: Ichoran + gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 + commits: 2 + linesAdded: 55 + linesDeleted: 16 + rank: 3 + newContributor: false + - username: mkubala + gravatar: https://avatars0.githubusercontent.com/u/328844?v=2&s=60 + commits: 1 + linesAdded: 1 + linesDeleted: 0 + rank: 4 + newContributor: false + - username: jedesah + gravatar: https://avatars1.githubusercontent.com/u/1780116?v=2&s=60 + commits: 1 + linesAdded: 23 + linesDeleted: 1 + rank: 4 + newContributor: false + - username: VladimirNik + gravatar: https://avatars2.githubusercontent.com/u/2835001?v=2&s=60 + commits: 1 + linesAdded: 78 + linesDeleted: 40 + rank: 4 + newContributor: false + - username: densh + gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 + commits: 1 + linesAdded: 14 + linesDeleted: 0 + rank: 4 + newContributor: false +--- diff --git a/contribute/scala-fame-data/_posts/2014-07-01-scala-fame-2014-06.md b/contribute/scala-fame-data/_posts/2014-07-01-scala-fame-2014-06.md new file mode 100644 index 0000000000..5f051d08a7 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2014-07-01-scala-fame-2014-06.md @@ -0,0 +1,98 @@ +--- +layout: famearchive +title: Contributors of June 2014 +fame-year: 2014 +fame-month: 6 +fame-month-str: June +fame-categories: + - category: Typesafe + authors: + - username: adriaanm + gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 + commits: 14 + linesAdded: 873 + linesDeleted: 661 + rank: 1 + newContributor: false + - username: retronym + gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 + commits: 8 + linesAdded: 166 + linesDeleted: 126 + rank: 2 + newContributor: false + - category: EPFL + authors: + - username: lrytz + gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 + commits: 16 + linesAdded: 1865 + linesDeleted: 437 + rank: 1 + newContributor: false + - username: xeno-by + gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 + commits: 4 + linesAdded: 164 + linesDeleted: 44 + rank: 2 + newContributor: false + - username: odersky + gravatar: https://avatars2.githubusercontent.com/u/795990?v=2&s=60 + commits: 1 + linesAdded: 36 + linesDeleted: 10 + rank: 3 + newContributor: false + - category: Community + authors: + - username: Ichoran + gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 + commits: 7 + linesAdded: 275 + linesDeleted: 57 + rank: 1 + newContributor: false + - username: jxcoder + gravatar: https://avatars1.githubusercontent.com/u/1075547?v=2&s=60 + commits: 4 + linesAdded: 41 + linesDeleted: 19 + rank: 2 + newContributor: true + - username: gourlaysama + gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 + commits: 2 + linesAdded: 20 + linesDeleted: 6 + rank: 3 + newContributor: false + - username: som-snytt + gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 + commits: 2 + linesAdded: 146 + linesDeleted: 41 + rank: 3 + newContributor: false + - username: jrudolph + gravatar: https://avatars1.githubusercontent.com/u/9868?v=2&s=60 + commits: 1 + linesAdded: 97 + linesDeleted: 4 + rank: 4 + newContributor: false + - username: Blaisorblade + gravatar: https://avatars2.githubusercontent.com/u/289960?v=2&s=60 + commits: 1 + linesAdded: 6 + linesDeleted: 1 + rank: 4 + newContributor: false + - username: densh + gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 + commits: 1 + linesAdded: 17 + linesDeleted: 5 + rank: 4 + newContributor: false +--- diff --git a/contribute/scala-fame-data/_posts/2014-08-01-scala-fame-2014-07.md b/contribute/scala-fame-data/_posts/2014-08-01-scala-fame-2014-07.md new file mode 100644 index 0000000000..c57474778d --- /dev/null +++ b/contribute/scala-fame-data/_posts/2014-08-01-scala-fame-2014-07.md @@ -0,0 +1,98 @@ +--- +layout: famearchive +title: Contributors of July 2014 +fame-year: 2014 +fame-month: 7 +fame-month-str: July +fame-categories: + - category: Typesafe + authors: + - username: adriaanm + gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 + commits: 31 + linesAdded: 775 + linesDeleted: 712 + rank: 1 + newContributor: false + - username: phaller + gravatar: https://avatars0.githubusercontent.com/u/289943?v=2&s=60 + commits: 3 + linesAdded: 161 + linesDeleted: 49 + rank: 2 + newContributor: false + - username: retronym + gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 + commits: 1 + linesAdded: 35 + linesDeleted: 34 + rank: 3 + newContributor: false + - category: EPFL + authors: + - username: lrytz + gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 + commits: 4 + linesAdded: 84 + linesDeleted: 29 + rank: 1 + newContributor: false + - category: Community + authors: + - username: som-snytt + gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 + commits: 11 + linesAdded: 330 + linesDeleted: 226 + rank: 1 + newContributor: false + - username: gourlaysama + gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 + commits: 5 + linesAdded: 217 + linesDeleted: 94 + rank: 2 + newContributor: false + - username: dhgarrette + gravatar: https://avatars2.githubusercontent.com/u/484190?v=2&s=60 + commits: 2 + linesAdded: 1 + linesDeleted: 3 + rank: 3 + newContributor: true + - username: pocket7878 + gravatar: https://avatars1.githubusercontent.com/u/236528?v=2&s=60 + commits: 2 + linesAdded: 21 + linesDeleted: 13 + rank: 3 + newContributor: true + - username: dgruntz + gravatar: https://avatars3.githubusercontent.com/u/1516800?v=2&s=60 + commits: 2 + linesAdded: 4 + linesDeleted: 4 + rank: 3 + newContributor: false + - username: Ichoran + gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 + commits: 1 + linesAdded: 26 + linesDeleted: 9 + rank: 4 + newContributor: false + - username: kzys + gravatar: https://avatars2.githubusercontent.com/u/19111?v=2&s=60 + commits: 1 + linesAdded: 19 + linesDeleted: 0 + rank: 4 + newContributor: false + - username: densh + gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 + commits: 1 + linesAdded: 3 + linesDeleted: 1 + rank: 4 + newContributor: false +--- diff --git a/contribute/scala-fame-data/_posts/2014-09-01-scala-fame-2014-08.md b/contribute/scala-fame-data/_posts/2014-09-01-scala-fame-2014-08.md index 1393e01705..afef86d3be 100644 --- a/contribute/scala-fame-data/_posts/2014-09-01-scala-fame-2014-08.md +++ b/contribute/scala-fame-data/_posts/2014-09-01-scala-fame-2014-08.md @@ -46,6 +46,13 @@ fame-categories: linesDeleted: 543 rank: 1 newContributor: false + - username: gbasler + gravatar: https://avatars1.githubusercontent.com/u/273035?v=2&s=60 + commits: 1 + linesAdded: 14 + linesDeleted: 22 + rank: 2 + newContributor: false - username: dgruntz gravatar: https://avatars3.githubusercontent.com/u/1516800?v=2&s=60 commits: 1 diff --git a/contribute/scala-fame-data/_posts/2014-10-01-scala-fame-2014-09.md b/contribute/scala-fame-data/_posts/2014-10-01-scala-fame-2014-09.md new file mode 100644 index 0000000000..ee67016186 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2014-10-01-scala-fame-2014-09.md @@ -0,0 +1,84 @@ +--- +layout: famearchive +title: Contributors of September 2014 +fame-year: 2014 +fame-month: 9 +fame-month-str: September +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 + commits: 12 + linesAdded: 182 + linesDeleted: 23 + rank: 1 + newContributor: false + - username: dragos + gravatar: https://avatars2.githubusercontent.com/u/133742?v=2&s=60 + commits: 1 + linesAdded: 169 + linesDeleted: 169 + rank: 2 + newContributor: false + - category: EPFL + authors: + - username: lrytz + gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 + commits: 6 + linesAdded: 262 + linesDeleted: 85 + rank: 1 + newContributor: false + - username: xeno-by + gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 + commits: 3 + linesAdded: 1272 + linesDeleted: 1240 + rank: 2 + newContributor: false + - category: Community + authors: + - username: gourlaysama + gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 + commits: 9 + linesAdded: 1782 + linesDeleted: 1227 + rank: 1 + newContributor: false + - username: som-snytt + gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 + commits: 4 + linesAdded: 305 + linesDeleted: 125 + rank: 2 + newContributor: false + - username: puffnfresh + gravatar: https://avatars1.githubusercontent.com/u/37715?v=2&s=60 + commits: 3 + linesAdded: 42 + linesDeleted: 7 + rank: 3 + newContributor: false + - username: Ichoran + gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 + commits: 2 + linesAdded: 12 + linesDeleted: 1 + rank: 4 + newContributor: false + - username: gbasler + gravatar: https://avatars1.githubusercontent.com/u/273035?v=2&s=60 + commits: 1 + linesAdded: 115 + linesDeleted: 41 + rank: 5 + newContributor: false + - username: soc + gravatar: https://avatars0.githubusercontent.com/u/42493?v=2&s=60 + commits: 1 + linesAdded: 4 + linesDeleted: 1 + rank: 5 + newContributor: false +--- From bd730a6d4d147e313828cf8155e71a8ac47069be Mon Sep 17 00:00:00 2001 From: Fabien Salvi Date: Fri, 24 Oct 2014 16:48:29 +0200 Subject: [PATCH 0048/3075] Add 2013 scala-fame data --- .../_posts/2013-02-01-scala-fame-2013-01.md | 175 ++++++++++++++++++ .../_posts/2013-11-01-scala-fame-2013-10.md | 105 +++++++++++ .../_posts/2013-12-01-scala-fame-2013-11.md | 126 +++++++++++++ .../_posts/2014-01-01-scala-fame-2013-12.md | 147 +++++++++++++++ 4 files changed, 553 insertions(+) create mode 100644 contribute/scala-fame-data/_posts/2013-02-01-scala-fame-2013-01.md create mode 100644 contribute/scala-fame-data/_posts/2013-11-01-scala-fame-2013-10.md create mode 100644 contribute/scala-fame-data/_posts/2013-12-01-scala-fame-2013-11.md create mode 100644 contribute/scala-fame-data/_posts/2014-01-01-scala-fame-2013-12.md diff --git a/contribute/scala-fame-data/_posts/2013-02-01-scala-fame-2013-01.md b/contribute/scala-fame-data/_posts/2013-02-01-scala-fame-2013-01.md new file mode 100644 index 0000000000..68e990a7b7 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2013-02-01-scala-fame-2013-01.md @@ -0,0 +1,175 @@ +--- +layout: famearchive +title: Contributors of January 2013 +fame-year: 2013 +fame-month: 1 +fame-month-str: January +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 + commits: 67 + linesAdded: 7112 + linesDeleted: 3063 + rank: 1 + newContributor: false + - username: paulp + gravatar: https://avatars2.githubusercontent.com/u/9135?v=2&s=60 + commits: 37 + linesAdded: 1812 + linesDeleted: 1158 + rank: 2 + newContributor: false + - username: adriaanm + gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 + commits: 22 + linesAdded: 1397 + linesDeleted: 561 + rank: 3 + newContributor: false + - username: JamesIry + gravatar: https://avatars0.githubusercontent.com/u/478012?v=2&s=60 + commits: 20 + linesAdded: 1156 + linesDeleted: 208 + rank: 4 + newContributor: false + - username: gkossakowski + gravatar: https://avatars0.githubusercontent.com/u/4217?v=2&s=60 + commits: 5 + linesAdded: 422 + linesDeleted: 9 + rank: 5 + newContributor: false + - username: viktorklang + gravatar: https://avatars0.githubusercontent.com/u/10871?v=2&s=60 + commits: 2 + linesAdded: 187 + linesDeleted: 12 + rank: 6 + newContributor: false + - username: phaller + gravatar: https://avatars0.githubusercontent.com/u/289943?v=2&s=60 + commits: 2 + linesAdded: 21 + linesDeleted: 42 + rank: 6 + newContributor: false + - username: dragos + gravatar: https://avatars2.githubusercontent.com/u/133742?v=2&s=60 + commits: 1 + linesAdded: 6 + linesDeleted: 26 + rank: 7 + newContributor: false + - category: EPFL + authors: + - username: xeno-by + gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 + commits: 28 + linesAdded: 8416 + linesDeleted: 2758 + rank: 1 + newContributor: false + - username: lrytz + gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 + commits: 8 + linesAdded: 1189 + linesDeleted: 418 + rank: 2 + newContributor: false + - username: heathermiller + gravatar: https://avatars0.githubusercontent.com/u/687163?v=2&s=60 + commits: 2 + linesAdded: 100 + linesDeleted: 15 + rank: 3 + newContributor: false + - username: namin + gravatar: https://avatars2.githubusercontent.com/u/6441?v=2&s=60 + commits: 1 + linesAdded: 23 + linesDeleted: 4 + rank: 4 + newContributor: false + - username: vjovanov + gravatar: https://avatars3.githubusercontent.com/u/352820?v=2&s=60 + commits: 1 + linesAdded: 38 + linesDeleted: 2 + rank: 4 + newContributor: false + - category: Community + authors: + - username: soc + gravatar: https://avatars0.githubusercontent.com/u/42493?v=2&s=60 + commits: 13 + linesAdded: 886 + linesDeleted: 3152 + rank: 1 + newContributor: false + - username: kzys + gravatar: https://avatars2.githubusercontent.com/u/19111?v=2&s=60 + commits: 7 + linesAdded: 79 + linesDeleted: 40 + rank: 2 + newContributor: false + - username: danielhopkins + gravatar: https://avatars3.githubusercontent.com/u/91909?v=2&s=60 + commits: 2 + linesAdded: 146 + linesDeleted: 146 + rank: 3 + newContributor: true + - username: ViniciusMiana + gravatar: https://avatars1.githubusercontent.com/u/2053546?v=2&s=60 + commits: 2 + linesAdded: 47 + linesDeleted: 8 + rank: 3 + newContributor: false + - username: Blaisorblade + gravatar: https://avatars2.githubusercontent.com/u/289960?v=2&s=60 + commits: 2 + linesAdded: 53 + linesDeleted: 6 + rank: 3 + newContributor: false + - username: som-snytt + gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 + commits: 2 + linesAdded: 236 + linesDeleted: 183 + rank: 3 + newContributor: false + - username: eed3si9n + gravatar: https://avatars1.githubusercontent.com/u/184683?v=2&s=60 + commits: 1 + linesAdded: 35 + linesDeleted: 2 + rank: 4 + newContributor: false + - username: mt2309 + gravatar: https://avatars2.githubusercontent.com/u/816245?v=2&s=60 + commits: 1 + linesAdded: 24 + linesDeleted: 0 + rank: 4 + newContributor: false + - username: puffnfresh + gravatar: https://avatars1.githubusercontent.com/u/37715?v=2&s=60 + commits: 1 + linesAdded: 39 + linesDeleted: 3 + rank: 4 + newContributor: false + - username: khernyo + gravatar: https://avatars3.githubusercontent.com/u/447532?v=2&s=60 + commits: 1 + linesAdded: 2 + linesDeleted: 3 + rank: 4 + newContributor: false +--- diff --git a/contribute/scala-fame-data/_posts/2013-11-01-scala-fame-2013-10.md b/contribute/scala-fame-data/_posts/2013-11-01-scala-fame-2013-10.md new file mode 100644 index 0000000000..557955d60c --- /dev/null +++ b/contribute/scala-fame-data/_posts/2013-11-01-scala-fame-2013-10.md @@ -0,0 +1,105 @@ +--- +layout: famearchive +title: Contributors of October 2013 +fame-year: 2013 +fame-month: 10 +fame-month-str: October +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 + commits: 52 + linesAdded: 1917 + linesDeleted: 1778 + rank: 1 + newContributor: false + - username: adriaanm + gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 + commits: 18 + linesAdded: 1648 + linesDeleted: 1591 + rank: 2 + newContributor: false + - username: paulp + gravatar: https://avatars2.githubusercontent.com/u/9135?v=2&s=60 + commits: 9 + linesAdded: 871 + linesDeleted: 1346 + rank: 3 + newContributor: false + - username: huitseeker + gravatar: https://avatars2.githubusercontent.com/u/4142?v=2&s=60 + commits: 1 + linesAdded: 3 + linesDeleted: 0 + rank: 4 + newContributor: false + - category: EPFL + authors: + - username: xeno-by + gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 + commits: 9 + linesAdded: 398 + linesDeleted: 2260 + rank: 1 + newContributor: false + - username: axel22 + gravatar: https://avatars1.githubusercontent.com/u/151774?v=2&s=60 + commits: 1 + linesAdded: 201 + linesDeleted: 74 + rank: 2 + newContributor: false + - category: Community + authors: + - username: densh + gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 + commits: 18 + linesAdded: 766 + linesDeleted: 422 + rank: 1 + newContributor: false + - username: som-snytt + gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 + commits: 4 + linesAdded: 114 + linesDeleted: 58 + rank: 2 + newContributor: false + - username: etaty + gravatar: https://avatars3.githubusercontent.com/u/461170?v=2&s=60 + commits: 2 + linesAdded: 2 + linesDeleted: 2 + rank: 3 + newContributor: false + - username: dotta + gravatar: https://avatars2.githubusercontent.com/u/703748?v=2&s=60 + commits: 2 + linesAdded: 68 + linesDeleted: 6 + rank: 3 + newContributor: false + - username: qerub + gravatar: https://avatars2.githubusercontent.com/u/636?v=2&s=60 + commits: 1 + linesAdded: 8 + linesDeleted: 0 + rank: 4 + newContributor: false + - username: gourlaysama + gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 + commits: 1 + linesAdded: 31 + linesDeleted: 1 + rank: 4 + newContributor: false + - username: Ichoran + gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 + commits: 1 + linesAdded: 215 + linesDeleted: 25 + rank: 4 + newContributor: false +--- diff --git a/contribute/scala-fame-data/_posts/2013-12-01-scala-fame-2013-11.md b/contribute/scala-fame-data/_posts/2013-12-01-scala-fame-2013-11.md new file mode 100644 index 0000000000..7fba955998 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2013-12-01-scala-fame-2013-11.md @@ -0,0 +1,126 @@ +--- +layout: famearchive +title: Contributors of November 2013 +fame-year: 2013 +fame-month: 11 +fame-month-str: November +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 + commits: 44 + linesAdded: 1814 + linesDeleted: 1372 + rank: 1 + newContributor: false + - username: adriaanm + gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 + commits: 20 + linesAdded: 1945 + linesDeleted: 1463 + rank: 2 + newContributor: false + - username: paulp + gravatar: https://avatars2.githubusercontent.com/u/9135?v=2&s=60 + commits: 4 + linesAdded: 62 + linesDeleted: 659 + rank: 3 + newContributor: false + - username: huitseeker + gravatar: https://avatars2.githubusercontent.com/u/4142?v=2&s=60 + commits: 2 + linesAdded: 137 + linesDeleted: 87 + rank: 4 + newContributor: false + - username: phaller + gravatar: https://avatars0.githubusercontent.com/u/289943?v=2&s=60 + commits: 1 + linesAdded: 105 + linesDeleted: 101 + rank: 5 + newContributor: false + - category: EPFL + authors: + - username: xeno-by + gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 + commits: 5 + linesAdded: 82 + linesDeleted: 12 + rank: 1 + newContributor: false + - username: heathermiller + gravatar: https://avatars0.githubusercontent.com/u/687163?v=2&s=60 + commits: 1 + linesAdded: 8 + linesDeleted: 5 + rank: 2 + newContributor: false + - category: Community + authors: + - username: densh + gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 + commits: 10 + linesAdded: 1089 + linesDeleted: 884 + rank: 1 + newContributor: false + - username: skyluc + gravatar: https://avatars3.githubusercontent.com/u/1098830?v=2&s=60 + commits: 6 + linesAdded: 1911 + linesDeleted: 53 + rank: 2 + newContributor: false + - username: dotta + gravatar: https://avatars2.githubusercontent.com/u/703748?v=2&s=60 + commits: 6 + linesAdded: 64 + linesDeleted: 47 + rank: 2 + newContributor: false + - username: som-snytt + gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 + commits: 6 + linesAdded: 499 + linesDeleted: 197 + rank: 2 + newContributor: false + - username: soc + gravatar: https://avatars0.githubusercontent.com/u/42493?v=2&s=60 + commits: 5 + linesAdded: 280 + linesDeleted: 97 + rank: 3 + newContributor: false + - username: sschaef + gravatar: https://avatars2.githubusercontent.com/u/488530?v=2&s=60 + commits: 4 + linesAdded: 182 + linesDeleted: 12 + rank: 4 + newContributor: false + - username: xuwei-k + gravatar: https://avatars3.githubusercontent.com/u/389787?v=2&s=60 + commits: 2 + linesAdded: 3 + linesDeleted: 3 + rank: 5 + newContributor: false + - username: Ichoran + gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 + commits: 2 + linesAdded: 1179 + linesDeleted: 0 + rank: 5 + newContributor: false + - username: Blaisorblade + gravatar: https://avatars2.githubusercontent.com/u/289960?v=2&s=60 + commits: 1 + linesAdded: 3 + linesDeleted: 3 + rank: 6 + newContributor: false +--- diff --git a/contribute/scala-fame-data/_posts/2014-01-01-scala-fame-2013-12.md b/contribute/scala-fame-data/_posts/2014-01-01-scala-fame-2013-12.md new file mode 100644 index 0000000000..80c4139b10 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2014-01-01-scala-fame-2013-12.md @@ -0,0 +1,147 @@ +--- +layout: famearchive +title: Contributors of December 2013 +fame-year: 2013 +fame-month: 12 +fame-month-str: December +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 + commits: 28 + linesAdded: 901 + linesDeleted: 215 + rank: 1 + newContributor: false + - username: adriaanm + gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 + commits: 21 + linesAdded: 1386 + linesDeleted: 16746 + rank: 2 + newContributor: false + - username: paulp + gravatar: https://avatars2.githubusercontent.com/u/9135?v=2&s=60 + commits: 9 + linesAdded: 899 + linesDeleted: 409 + rank: 3 + newContributor: false + - username: huitseeker + gravatar: https://avatars2.githubusercontent.com/u/4142?v=2&s=60 + commits: 3 + linesAdded: 45 + linesDeleted: 38 + rank: 4 + newContributor: false + - category: EPFL + authors: + - username: xeno-by + gravatar: https://avatars1.githubusercontent.com/u/609152?v=2&s=60 + commits: 30 + linesAdded: 2170 + linesDeleted: 984 + rank: 1 + newContributor: false + - username: magarciaEPFL + gravatar: https://avatars2.githubusercontent.com/u/1249748?v=2&s=60 + commits: 5 + linesAdded: 47 + linesDeleted: 17 + rank: 2 + newContributor: false + - category: Community + authors: + - username: densh + gravatar: https://avatars2.githubusercontent.com/u/320966?v=2&s=60 + commits: 20 + linesAdded: 1604 + linesDeleted: 703 + rank: 1 + newContributor: false + - username: soc + gravatar: https://avatars0.githubusercontent.com/u/42493?v=2&s=60 + commits: 11 + linesAdded: 728 + linesDeleted: 606 + rank: 2 + newContributor: false + - username: Ichoran + gravatar: https://avatars3.githubusercontent.com/u/2298644?v=2&s=60 + commits: 8 + linesAdded: 1490 + linesDeleted: 286 + rank: 3 + newContributor: false + - username: som-snytt + gravatar: https://avatars2.githubusercontent.com/u/369425?v=2&s=60 + commits: 6 + linesAdded: 382 + linesDeleted: 224 + rank: 4 + newContributor: false + - username: dotta + gravatar: https://avatars2.githubusercontent.com/u/703748?v=2&s=60 + commits: 5 + linesAdded: 265 + linesDeleted: 13 + rank: 5 + newContributor: false + - username: VladimirNik + gravatar: https://avatars2.githubusercontent.com/u/2835001?v=2&s=60 + commits: 2 + linesAdded: 7 + linesDeleted: 8 + rank: 6 + newContributor: false + - username: rklaehn + gravatar: https://avatars0.githubusercontent.com/u/248257?v=2&s=60 + commits: 2 + linesAdded: 2 + linesDeleted: 83 + rank: 6 + newContributor: false + - username: qerub + gravatar: https://avatars2.githubusercontent.com/u/636?v=2&s=60 + commits: 1 + linesAdded: 10 + linesDeleted: 11 + rank: 7 + newContributor: false + - username: jrudolph + gravatar: https://avatars1.githubusercontent.com/u/9868?v=2&s=60 + commits: 1 + linesAdded: 4 + linesDeleted: 4 + rank: 7 + newContributor: false + - username: skyluc + gravatar: https://avatars3.githubusercontent.com/u/1098830?v=2&s=60 + commits: 1 + linesAdded: 112 + linesDeleted: 54 + rank: 7 + newContributor: false + - username: non + gravatar: https://avatars3.githubusercontent.com/u/218045?v=2&s=60 + commits: 1 + linesAdded: 19 + linesDeleted: 8 + rank: 7 + newContributor: false + - username: xuwei-k + gravatar: https://avatars3.githubusercontent.com/u/389787?v=2&s=60 + commits: 1 + linesAdded: 1 + linesDeleted: 1 + rank: 7 + newContributor: false + - username: gourlaysama + gravatar: https://avatars2.githubusercontent.com/u/733438?v=2&s=60 + commits: 1 + linesAdded: 136 + linesDeleted: 55 + rank: 7 + newContributor: false +--- From 3d71e5bd8e4dae6dc1d318e8d72768b49e97bede Mon Sep 17 00:00:00 2001 From: Fabien Salvi Date: Mon, 3 Nov 2014 16:34:38 +0100 Subject: [PATCH 0049/3075] Add scala-fame data --- .../_posts/2014-11-01-scala-fame-2014-10.md | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 contribute/scala-fame-data/_posts/2014-11-01-scala-fame-2014-10.md diff --git a/contribute/scala-fame-data/_posts/2014-11-01-scala-fame-2014-10.md b/contribute/scala-fame-data/_posts/2014-11-01-scala-fame-2014-10.md new file mode 100644 index 0000000000..0c957577fb --- /dev/null +++ b/contribute/scala-fame-data/_posts/2014-11-01-scala-fame-2014-10.md @@ -0,0 +1,63 @@ +--- +layout: famearchive +title: Contributors of October 2014 +fame-year: 2014 +fame-month: 10 +fame-month-str: October +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://avatars0.githubusercontent.com/u/65551?v=2&s=60 + commits: 11 + linesAdded: 414 + linesDeleted: 51 + rank: 1 + newContributor: false + - username: gkossakowski + gravatar: https://avatars0.githubusercontent.com/u/4217?v=2&s=60 + commits: 2 + linesAdded: 2 + linesDeleted: 2 + rank: 2 + newContributor: false + - username: adriaanm + gravatar: https://avatars2.githubusercontent.com/u/91083?v=2&s=60 + commits: 2 + linesAdded: 54 + linesDeleted: 18 + rank: 2 + newContributor: false + - category: EPFL + authors: + - username: lrytz + gravatar: https://avatars3.githubusercontent.com/u/119636?v=2&s=60 + commits: 4 + linesAdded: 146 + linesDeleted: 171 + rank: 1 + newContributor: false + - category: Community + authors: + - username: roberthoedicke + gravatar: https://avatars0.githubusercontent.com/u/9093826?v=2&s=60 + commits: 9 + linesAdded: 15 + linesDeleted: 15 + rank: 1 + newContributor: true + - username: puffnfresh + gravatar: https://avatars1.githubusercontent.com/u/37715?v=2&s=60 + commits: 1 + linesAdded: 19 + linesDeleted: 10 + rank: 2 + newContributor: false + - username: Blaisorblade + gravatar: https://avatars2.githubusercontent.com/u/289960?v=2&s=60 + commits: 1 + linesAdded: 0 + linesDeleted: 93 + rank: 2 + newContributor: false +--- From 84d53a941025d8188d7ce2f8312748ed23ae6de6 Mon Sep 17 00:00:00 2001 From: Fabien Salvi Date: Wed, 3 Dec 2014 16:47:25 +0100 Subject: [PATCH 0050/3075] Add scala-fame data --- .../_posts/2014-12-01-scala-fame-2014-11.md | 112 ++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 contribute/scala-fame-data/_posts/2014-12-01-scala-fame-2014-11.md diff --git a/contribute/scala-fame-data/_posts/2014-12-01-scala-fame-2014-11.md b/contribute/scala-fame-data/_posts/2014-12-01-scala-fame-2014-11.md new file mode 100644 index 0000000000..3c95eb2521 --- /dev/null +++ b/contribute/scala-fame-data/_posts/2014-12-01-scala-fame-2014-11.md @@ -0,0 +1,112 @@ +--- +layout: famearchive +title: Contributors of November 2014 +fame-year: 2014 +fame-month: 11 +fame-month-str: November +fame-categories: + - category: Typesafe + authors: + - username: retronym + gravatar: https://avatars1.githubusercontent.com/u/65551?v=3&s=60 + commits: 24 + linesAdded: 650 + linesDeleted: 90 + rank: 1 + newContributor: false + - username: adriaanm + gravatar: https://avatars3.githubusercontent.com/u/91083?v=3&s=60 + commits: 3 + linesAdded: 208 + linesDeleted: 54 + rank: 2 + newContributor: false + - username: phaller + gravatar: https://avatars1.githubusercontent.com/u/289943?v=3&s=60 + commits: 1 + linesAdded: 10 + linesDeleted: 8 + rank: 3 + newContributor: false + - category: EPFL + authors: + - username: lrytz + gravatar: https://avatars2.githubusercontent.com/u/119636?v=3&s=60 + commits: 6 + linesAdded: 782 + linesDeleted: 32 + rank: 1 + newContributor: false + - username: heathermiller + gravatar: https://avatars1.githubusercontent.com/u/687163?v=3&s=60 + commits: 2 + linesAdded: 64 + linesDeleted: 66 + rank: 2 + newContributor: false + - category: Community + authors: + - username: gourlaysama + gravatar: https://avatars3.githubusercontent.com/u/733438?v=3&s=60 + commits: 7 + linesAdded: 245 + linesDeleted: 83 + rank: 1 + newContributor: false + - username: som-snytt + gravatar: https://avatars3.githubusercontent.com/u/369425?v=3&s=60 + commits: 3 + linesAdded: 53 + linesDeleted: 53 + rank: 2 + newContributor: false + - username: advancedxy + gravatar: https://avatars1.githubusercontent.com/u/807537?v=3&s=60 + commits: 2 + linesAdded: 2 + linesDeleted: 2 + rank: 3 + newContributor: true + - username: kanielc + gravatar: https://avatars1.githubusercontent.com/u/1334074?v=3&s=60 + commits: 2 + linesAdded: 3 + linesDeleted: 3 + rank: 3 + newContributor: true + - username: gdickinson + gravatar: https://avatars3.githubusercontent.com/u/1130928?v=3&s=60 + commits: 2 + linesAdded: 0 + linesDeleted: 380 + rank: 3 + newContributor: true + - username: Ichoran + gravatar: https://avatars2.githubusercontent.com/u/2298644?v=3&s=60 + commits: 2 + linesAdded: 35 + linesDeleted: 18 + rank: 3 + newContributor: false + - username: ruippeixotog + gravatar: https://avatars1.githubusercontent.com/u/613493?v=3&s=60 + commits: 1 + linesAdded: 81 + linesDeleted: 8 + rank: 4 + newContributor: false + - username: mpociecha + gravatar: https://avatars0.githubusercontent.com/u/6143494?v=3&s=60 + commits: 1 + linesAdded: 5 + linesDeleted: 2 + rank: 4 + newContributor: false + - username: soc + gravatar: https://avatars1.githubusercontent.com/u/42493?v=3&s=60 + commits: 1 + linesAdded: 1 + linesDeleted: 1 + rank: 4 + newContributor: false +--- From def0d83bc4a8ae5ab2c7d07928f1717eec682e0d Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Mon, 12 Jan 2015 09:52:21 -0800 Subject: [PATCH 0051/3075] Removed PHP issues page in favor of direct JIRA queries. --- contribute/community-tickets.md | 10 -------- contribute/guide.md | 2 +- contribute/index.md | 45 +++++++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 16 deletions(-) delete mode 100644 contribute/community-tickets.md diff --git a/contribute/community-tickets.md b/contribute/community-tickets.md deleted file mode 100644 index e458d3b6f2..0000000000 --- a/contribute/community-tickets.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -layout: page-full-width -title: Community tickets ---- - -Below is a selection of tickets from -[Scala's bug tracker](https://issues.scala-lang.org/) -that we think are a good starting point for you, as the community. - -
diff --git a/contribute/guide.md b/contribute/guide.md index ac27e53719..9446e6ce9c 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -21,7 +21,7 @@ title: Contributing guide
-

Community issues

+

Community issues

Get cracking on some easy to approach issues.

diff --git a/contribute/index.md b/contribute/index.md index d2402cf4d2..d1ba675f05 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -23,9 +23,44 @@ An easy but very important way to contribute to Scala is to ### Compiler and other tools -Want to dive into the hardcore business? Check out our -[selection of community tickets](./community-tickets.html), -which are good starting points to contributing to the compiler and -surrounding tools, like ScalaDoc. - More info in our [contributing guide](./guide.html). + +### Community Tickets + +The following links provide starting points for +various contributor activities: + +
+
+
+

Documentation

+

Help augment or correct the documentation.

+
+
+

Core Libraries

+

Community bugs and enhancements on the core libs.

+
+
+ +
+
+

Tools

+

Help with the Scala tool chain.

+
+
+

Compiler

+

Ready for a challenge? Here's the compiler bugs.

+
+
+ +
+
+

Bugs

+

All bugs marked with the label community.

+
+
+

All Issues

+

Bugs + Enhancements marked with the label community.

+
+
+
From 76fcdfafa32914a60a0dd16e0ee7c75094e9682f Mon Sep 17 00:00:00 2001 From: Fabien Salvi Date: Wed, 14 Jan 2015 11:24:27 +0100 Subject: [PATCH 0052/3075] Add scala-fame data --- .../_posts/2015-01-01-scala-fame-2014-12.md | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 contribute/scala-fame-data/_posts/2015-01-01-scala-fame-2014-12.md diff --git a/contribute/scala-fame-data/_posts/2015-01-01-scala-fame-2014-12.md b/contribute/scala-fame-data/_posts/2015-01-01-scala-fame-2014-12.md new file mode 100644 index 0000000000..c11348b33a --- /dev/null +++ b/contribute/scala-fame-data/_posts/2015-01-01-scala-fame-2014-12.md @@ -0,0 +1,70 @@ +--- +layout: famearchive +title: Contributors of December 2014 +fame-year: 2014 +fame-month: 12 +fame-month-str: December +fame-categories: + - category: Typesafe + authors: + - username: adriaanm + gravatar: https://avatars3.githubusercontent.com/u/91083?v=3&s=60 + commits: 2 + linesAdded: 962 + linesDeleted: 290 + rank: 1 + newContributor: false + - username: retronym + gravatar: https://avatars1.githubusercontent.com/u/65551?v=3&s=60 + commits: 1 + linesAdded: 5 + linesDeleted: 1 + rank: 2 + newContributor: false + - category: EPFL + authors: + - username: lrytz + gravatar: https://avatars2.githubusercontent.com/u/119636?v=3&s=60 + commits: 4 + linesAdded: 61 + linesDeleted: 50 + rank: 1 + newContributor: false + - category: Community + authors: + - username: gbasler + gravatar: https://avatars0.githubusercontent.com/u/273035?v=3&s=60 + commits: 2 + linesAdded: 567 + linesDeleted: 1 + rank: 1 + newContributor: false + - username: kanielc + gravatar: https://avatars1.githubusercontent.com/u/1334074?v=3&s=60 + commits: 1 + linesAdded: 43 + linesDeleted: 6 + rank: 2 + newContributor: false + - username: xuwei-k + gravatar: https://avatars2.githubusercontent.com/u/389787?v=3&s=60 + commits: 1 + linesAdded: 2 + linesDeleted: 2 + rank: 2 + newContributor: false + - username: gourlaysama + gravatar: https://avatars3.githubusercontent.com/u/733438?v=3&s=60 + commits: 1 + linesAdded: 1 + linesDeleted: 1 + rank: 2 + newContributor: false + - username: som-snytt + gravatar: https://avatars3.githubusercontent.com/u/369425?v=3&s=60 + commits: 1 + linesAdded: 44 + linesDeleted: 3 + rank: 2 + newContributor: false +--- From fd4cf442dbb1b58fe5dd583068bbd1dcb2b07aca Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Wed, 14 Jan 2015 14:14:00 -0800 Subject: [PATCH 0053/3075] Add scaladoc contribution page and link up. --- contribute/contribute-scaladoc.md | 116 ++++++++++++++++++++++++++++++ contribute/index.md | 2 + 2 files changed, 118 insertions(+) create mode 100644 contribute/contribute-scaladoc.md diff --git a/contribute/contribute-scaladoc.md b/contribute/contribute-scaladoc.md new file mode 100644 index 0000000000..3bea0dea5a --- /dev/null +++ b/contribute/contribute-scaladoc.md @@ -0,0 +1,116 @@ +--- +layout: page +title: Scaladoc Contributions +--- + +This page is specific to scaladoc contributions. For contributions to the scala-lang +documentation site, [help with the documentation](http://docs.scala-lang.org/contribute.html). + +*Please note, these instructions cover contributions to the scala language and +core libraries only. For other scala projects please check those projects for +the contribution steps and guidelines. Thank you.* + +## Overview + +Since the scaladoc documentation is located in scala source code files, the +process for contributing scaladoc is similar to that of contributing bug-fixes +to the scala code base, but without the requirement that there be a JIRA bug +first (just use a `scaladoc/xxxx` branch name instead of `issue/NNNN`). +However, if an issue *does* exist, please use `issue/NNNN` (where NNNN is the bug id) +instead. + +If you would like to assist us by helping us find missing documentation and +submitting issues, [please read the following section](#submit-scaladoc-issues). +If you want to contribute scaladoc, +[jump down to the next section](#contribute-scaladoc). + +## Submit Scaladoc Issues + +You can also contribute by helping us to identify missing documentation. To do +this, [browse the current API documentation](http://www.scala-lang.org/api/current/) +and identify missing, incorrect or inadequate documentation. In particular pay +attention to the package objects for important packages (these often get overlooked +for documentation and are a good place for API overviews). + +If you find an issue, please log it in the [Scala issue browser](https://issues.scala-lang.org) +**after making sure it is not already logged as an issue**. To help with +disambiguation, please use the following format for issue title: + +* Use an action describing the work required. E.g. Add, Document, Correct, Remove +* Use the full package, class/trait/object name (or state package object if + that is the case). +* Extremely short description of what to do. +* More detail can (and should) go into the issue description, including a short + justification for the issue if it provides additional detail. + +Here is an example of the title and description for an example scaladoc issue: + +`Document scala.concurrent.Future object, include code examples` + +(note the explicit companion object called out in the title) + +and the description: + +`The methods on the Future companion object are critical` +`for using Futures effectively without blocking. Provide code` +`examples of how methods like sequence, transform, fold and` +`firstCompletedOf should be used.` + +In addition to following these conventions, please add `documentation` and +`community` labels to the issue, and put them in the `Documentation and API` +component so that they show up in the correct issue filters. + +## Contribute scaladoc + +### Required reading + +Please familiarize yourself with **all** of the following before contributing +scaladoc to save time, effort, mistakes and repetition. + +* [Forking the Repo](./hacker-guide.html#set-up) follow setup steps through + branch name. If providing scaladoc related to a JIRA issue, use `issue/NNNN` + or `ticket/NNNN` as the guide states. If providing scaladoc with no associated + JIRA issue, use `scaladoc/xxxx` instead, where xxxx is a descriptive but + short branch name, e.g. `scaladoc/future-object`. +* [Scaladoc basics](http://docs.scala-lang.org/overviews/scaladoc/basics.html) + covers the use of scaladoc tags, markdown and other features. +* [Scaladoc usage](http://docs.scala-lang.org/overviews/scaladoc/usage.html) if + you are unfamiliar with all of the features of scaladoc, e.g. switching between + companions, browsing package object documentation, searching, token searches + and so on. +* Prior to commit, be sure to read + [A note about git commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). +* Also read the Scala [Pull Request Policy](https://github.com/scala/scala/wiki/Pull-Request-Policy). + Some of this document will clearly not apply (like the sections on providing tests, + however see below for some special requirements for documentation). Do still read + the whole document though, and pay close attention to the title and commit + message formats, noting *present tense*, *length limits* and that it must merge + cleanly. Remember that the title of the pull request will become the commit + message when merged. **Also**, be sure to assign one or more reviewers to the PR, list of + reviewers is at the bottom of this document, but the quick version is to add + `Review by @dickwall` **in the pull request comments**. + +### Extra Requirements for Scaladoc Commits + +Although some of the requirements for bug fix pull requests are not needed for +scaladoc commits, here are the step by step requirements to ensure your scaladoc +PR is merged in smoothly: + +* Any and all code examples provided should *be correct, compile and run* as + expected (ensure this in the REPL or your IDE). +* Spelling must be checked for all written language *and* code examples where + possible. Most editors have some spell checking feature available. Obviously + scala code is likely to flag as mis-spelled sometimes, but any written language + should be checked. If you can also use a grammar checker, even better. We + *will* ask for spelling and grammar to be corrected before acceptance. +* You **must** also run `ant docs`, fix any problems and check the formatting and + layout of your changes. Again, corrections will be required if formatting or + layout are inadequate. After running `ant docs` the generated documents can be + found under the `build/scaladoc/` folders (probably in the `library` folder + but maybe under the others depending on what section of the scala source you + are working on). +* All of these steps are required to save time for both the reviewers and + contributors. It benefits everyone to ensure that the PR to merge process is + as smooth and streamlined as possible. + +Thanks for helping us improve the scaladoc. diff --git a/contribute/index.md b/contribute/index.md index d2402cf4d2..995617634d 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -20,6 +20,8 @@ how to efficiently report a bug. An easy but very important way to contribute to Scala is to [help with the documentation](http://docs.scala-lang.org/contribute.html). +If you want to [contribute to scaladoc](./contribute-scaladoc.html), the +process is slightly different, since scaladoc lives alongside the source code. ### Compiler and other tools From b049734092803dafea95e4318322ff0e6102ff33 Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Tue, 27 Jan 2015 09:20:21 -0800 Subject: [PATCH 0054/3075] Corrected JIRA search URL for compiler bugs. --- contribute/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/index.md b/contribute/index.md index d1ba675f05..65c9c501cd 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -48,7 +48,7 @@ various contributor activities:

Help with the Scala tool chain.

-

Compiler

+

Compiler

Ready for a challenge? Here's the compiler bugs.

From b53c6bd2d67eddb97f61c857ed35989425da73ee Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Thu, 29 Jan 2015 14:21:15 +0100 Subject: [PATCH 0055/3075] Wording tweaks --- contribute/contribute-scaladoc.md | 75 +++++++++++++++++-------------- contribute/index.md | 6 +-- 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/contribute/contribute-scaladoc.md b/contribute/contribute-scaladoc.md index 3bea0dea5a..d9bd931de3 100644 --- a/contribute/contribute-scaladoc.md +++ b/contribute/contribute-scaladoc.md @@ -1,38 +1,45 @@ --- layout: page -title: Scaladoc Contributions +title: Contribute to API Documentation --- -This page is specific to scaladoc contributions. For contributions to the scala-lang -documentation site, [help with the documentation](http://docs.scala-lang.org/contribute.html). +This page is specific to API documentation contributions – that is, API +documentation for +[Scala's standard library](http://scala-lang.org/api/current/#package) – +sometimes referred to as Scaladoc contributions. -*Please note, these instructions cover contributions to the scala language and -core libraries only. For other scala projects please check those projects for -the contribution steps and guidelines. Thank you.* +For contributions to tutorial and guide-style documentation on +[docs.scala-lang.org](http://docs.scala-lang.org), +see the ["doc-site"'s contribution guide](http://docs.scala-lang.org/contribute.html). + +*Please note, these instructions cover documentation contributions Scala core +libraries only. For other Scala projects please check those projects for the +contribution steps and guidelines. Thank you.* ## Overview -Since the scaladoc documentation is located in scala source code files, the -process for contributing scaladoc is similar to that of contributing bug-fixes -to the scala code base, but without the requirement that there be a JIRA bug -first (just use a `scaladoc/xxxx` branch name instead of `issue/NNNN`). -However, if an issue *does* exist, please use `issue/NNNN` (where NNNN is the bug id) +Since API documentation is located in Scala source code files, the +process for contributing API documentation is similar to that of contributing bug-fixes +to the Scala code base, but without the requirement that there be an issue filed on JIRA +first (when forking/branching, just use a `scaladoc/xxxx` branch name instead of `issue/NNNN`). +However, if an issue *does* exist, please use `issue/NNNN` (where NNNN is the ticket number) instead. If you would like to assist us by helping us find missing documentation and -submitting issues, [please read the following section](#submit-scaladoc-issues). -If you want to contribute scaladoc, -[jump down to the next section](#contribute-scaladoc). +submitting bug reports for existing documentation, +[please read the following section](#contribute-api-documentation-bug-reports). +If you want to contribute new API documentation, +[jump down to the next section](#contribute-new-api-documentation). -## Submit Scaladoc Issues +## Contribute API Documentation Bug Reports -You can also contribute by helping us to identify missing documentation. To do -this, [browse the current API documentation](http://www.scala-lang.org/api/current/) -and identify missing, incorrect or inadequate documentation. In particular pay -attention to the package objects for important packages (these often get overlooked -for documentation and are a good place for API overviews). +One good way to contribute is by helping us to identify missing documentation. To do +this, [browse the current API documentationn](http://www.scala-lang.org/api/current/) +and identify missing, incorrect or inadequate documentation. A good place to start is +is package objects for important packages (these often get overlooked for documentation +and are a good place for API overviews). -If you find an issue, please log it in the [Scala issue browser](https://issues.scala-lang.org) +If you find an issue, please log it in the [Scala issue tracker](https://issues.scala-lang.org) **after making sure it is not already logged as an issue**. To help with disambiguation, please use the following format for issue title: @@ -43,7 +50,7 @@ disambiguation, please use the following format for issue title: * More detail can (and should) go into the issue description, including a short justification for the issue if it provides additional detail. -Here is an example of the title and description for an example scaladoc issue: +Here is an example of the title and description for an example API documentation issue: `Document scala.concurrent.Future object, include code examples` @@ -60,22 +67,22 @@ In addition to following these conventions, please add `documentation` and `community` labels to the issue, and put them in the `Documentation and API` component so that they show up in the correct issue filters. -## Contribute scaladoc +## Contribute New API Documentation -### Required reading +### Required Reading Please familiarize yourself with **all** of the following before contributing -scaladoc to save time, effort, mistakes and repetition. +new API documentation to save time, effort, mistakes and repetition. * [Forking the Repo](./hacker-guide.html#set-up) follow setup steps through - branch name. If providing scaladoc related to a JIRA issue, use `issue/NNNN` - or `ticket/NNNN` as the guide states. If providing scaladoc with no associated + branch name. If providing new documentation related to an existing JIRA issue, use `issue/NNNN` + or `ticket/NNNN` as the guide states. If providing API documentation with no associated JIRA issue, use `scaladoc/xxxx` instead, where xxxx is a descriptive but short branch name, e.g. `scaladoc/future-object`. -* [Scaladoc basics](http://docs.scala-lang.org/overviews/scaladoc/basics.html) +* [Scaladoc for library authors](http://docs.scala-lang.org/overviews/scaladoc/for-library-authors.html) covers the use of scaladoc tags, markdown and other features. -* [Scaladoc usage](http://docs.scala-lang.org/overviews/scaladoc/usage.html) if - you are unfamiliar with all of the features of scaladoc, e.g. switching between +* [Scaladoc's interface](http://docs.scala-lang.org/overviews/scaladoc/interface.html) + covers all of the features of Scaladoc's interface, e.g. switching between companions, browsing package object documentation, searching, token searches and so on. * Prior to commit, be sure to read @@ -93,24 +100,24 @@ scaladoc to save time, effort, mistakes and repetition. ### Extra Requirements for Scaladoc Commits Although some of the requirements for bug fix pull requests are not needed for -scaladoc commits, here are the step by step requirements to ensure your scaladoc +API documentation commits, here are the step by step requirements to ensure your API documentation PR is merged in smoothly: * Any and all code examples provided should *be correct, compile and run* as expected (ensure this in the REPL or your IDE). * Spelling must be checked for all written language *and* code examples where possible. Most editors have some spell checking feature available. Obviously - scala code is likely to flag as mis-spelled sometimes, but any written language + Scala code is likely to flag as mis-spelled sometimes, but any written language should be checked. If you can also use a grammar checker, even better. We *will* ask for spelling and grammar to be corrected before acceptance. * You **must** also run `ant docs`, fix any problems and check the formatting and layout of your changes. Again, corrections will be required if formatting or layout are inadequate. After running `ant docs` the generated documents can be found under the `build/scaladoc/` folders (probably in the `library` folder - but maybe under the others depending on what section of the scala source you + but maybe under the others depending on what section of the Scala source you are working on). * All of these steps are required to save time for both the reviewers and contributors. It benefits everyone to ensure that the PR to merge process is as smooth and streamlined as possible. -Thanks for helping us improve the scaladoc. +Thanks for helping us improve the Scaladoc API documentation! diff --git a/contribute/index.md b/contribute/index.md index 995617634d..5dda418cbf 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -19,9 +19,9 @@ how to efficiently report a bug. ### Help with the documentation An easy but very important way to contribute to Scala is to -[help with the documentation](http://docs.scala-lang.org/contribute.html). -If you want to [contribute to scaladoc](./contribute-scaladoc.html), the -process is slightly different, since scaladoc lives alongside the source code. +[help with the guide/tutorial-style documentation on docs.scala-lang.org](http://docs.scala-lang.org/contribute.html). +If you want to [contribute to Scala standard library API docmentation](./contribute-scaladoc.html), the +process is slightly different, since API documentation lives within Scala standard library source code. ### Compiler and other tools From b27128fd7967d882e274a80fc0328c7d4df6f4c0 Mon Sep 17 00:00:00 2001 From: Heather Miller Date: Thu, 29 Jan 2015 14:25:00 +0100 Subject: [PATCH 0056/3075] Some reorganization and tweaks --- contribute/index.md | 2 +- ...-scaladoc.md => scala-standard-library-api-documentation.md} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename contribute/{contribute-scaladoc.md => scala-standard-library-api-documentation.md} (99%) diff --git a/contribute/index.md b/contribute/index.md index 5dda418cbf..f2bed88bae 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -20,7 +20,7 @@ how to efficiently report a bug. An easy but very important way to contribute to Scala is to [help with the guide/tutorial-style documentation on docs.scala-lang.org](http://docs.scala-lang.org/contribute.html). -If you want to [contribute to Scala standard library API docmentation](./contribute-scaladoc.html), the +If you want to [contribute to Scala standard library API docmentation](./scala-standard-library-api-documentation.html), the process is slightly different, since API documentation lives within Scala standard library source code. ### Compiler and other tools diff --git a/contribute/contribute-scaladoc.md b/contribute/scala-standard-library-api-documentation.md similarity index 99% rename from contribute/contribute-scaladoc.md rename to contribute/scala-standard-library-api-documentation.md index d9bd931de3..ec41aee3cb 100644 --- a/contribute/contribute-scaladoc.md +++ b/contribute/scala-standard-library-api-documentation.md @@ -97,7 +97,7 @@ new API documentation to save time, effort, mistakes and repetition. reviewers is at the bottom of this document, but the quick version is to add `Review by @dickwall` **in the pull request comments**. -### Extra Requirements for Scaladoc Commits +### Extra Requirements for Scaladoc Documentation Commits Although some of the requirements for bug fix pull requests are not needed for API documentation commits, here are the step by step requirements to ensure your API documentation From 66f39d2e292cdc347b7d3c8d59835e83c59739f6 Mon Sep 17 00:00:00 2001 From: Justin Pihony Date: Mon, 2 Feb 2015 15:32:49 -0500 Subject: [PATCH 0057/3075] Fix the Forking url and grammatical consistency Review by @dickwall --- .../scala-standard-library-api-documentation.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/contribute/scala-standard-library-api-documentation.md b/contribute/scala-standard-library-api-documentation.md index ec41aee3cb..de5a970bbe 100644 --- a/contribute/scala-standard-library-api-documentation.md +++ b/contribute/scala-standard-library-api-documentation.md @@ -21,8 +21,9 @@ contribution steps and guidelines. Thank you.* Since API documentation is located in Scala source code files, the process for contributing API documentation is similar to that of contributing bug-fixes to the Scala code base, but without the requirement that there be an issue filed on JIRA -first (when forking/branching, just use a `scaladoc/xxxx` branch name instead of `issue/NNNN`). -However, if an issue *does* exist, please use `issue/NNNN` (where NNNN is the ticket number) +first. When forking/branching, just use a `scaladoc/xxxx` branch name, where xxxx is a +descriptive, but short branch name (e.g. `scaladoc/future-object`). +However, if an issue *does* exist, please use `issue/NNNN`, where NNNN is the ticket number, instead. If you would like to assist us by helping us find missing documentation and @@ -35,8 +36,8 @@ If you want to contribute new API documentation, One good way to contribute is by helping us to identify missing documentation. To do this, [browse the current API documentationn](http://www.scala-lang.org/api/current/) -and identify missing, incorrect or inadequate documentation. A good place to start is -is package objects for important packages (these often get overlooked for documentation +and identify missing, incorrect or inadequate documentation. A good place to start is +package objects for important packages (these often get overlooked for documentation and are a good place for API overviews). If you find an issue, please log it in the [Scala issue tracker](https://issues.scala-lang.org) @@ -74,11 +75,10 @@ component so that they show up in the correct issue filters. Please familiarize yourself with **all** of the following before contributing new API documentation to save time, effort, mistakes and repetition. -* [Forking the Repo](./hacker-guide.html#set-up) follow setup steps through - branch name. If providing new documentation related to an existing JIRA issue, use `issue/NNNN` +* [Forking the Repo](./hacker-guide.html#2_set_up) - follow the setup steps through + the Branch section. If providing new documentation related to an existing JIRA issue, use `issue/NNNN` or `ticket/NNNN` as the guide states. If providing API documentation with no associated - JIRA issue, use `scaladoc/xxxx` instead, where xxxx is a descriptive but - short branch name, e.g. `scaladoc/future-object`. + JIRA issue, use `scaladoc/xxxx` instead. * [Scaladoc for library authors](http://docs.scala-lang.org/overviews/scaladoc/for-library-authors.html) covers the use of scaladoc tags, markdown and other features. * [Scaladoc's interface](http://docs.scala-lang.org/overviews/scaladoc/interface.html) From f2a174cea939a311901274c187ffafadf17ebed0 Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Mon, 2 Feb 2015 14:10:10 -0800 Subject: [PATCH 0058/3075] Correct a couple of spelling typos on contribution pages. --- contribute/index.md | 2 +- .../scala-standard-library-api-documentation.md | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/contribute/index.md b/contribute/index.md index a065565a98..9ea981b115 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -5,7 +5,7 @@ title: Contribute The Scala programming language is an open source project with a very diverse community, where people from all over the world contribute their work, -with everyone benefitting from friendly help and advice, and +with everyone benefiting from friendly help and advice, and kindly helping others in return. So why not join the Scala community and help everyone make things better? diff --git a/contribute/scala-standard-library-api-documentation.md b/contribute/scala-standard-library-api-documentation.md index de5a970bbe..519c85a030 100644 --- a/contribute/scala-standard-library-api-documentation.md +++ b/contribute/scala-standard-library-api-documentation.md @@ -4,11 +4,11 @@ title: Contribute to API Documentation --- This page is specific to API documentation contributions – that is, API -documentation for -[Scala's standard library](http://scala-lang.org/api/current/#package) – +documentation for +[Scala's standard library](http://scala-lang.org/api/current/#package) – sometimes referred to as Scaladoc contributions. -For contributions to tutorial and guide-style documentation on +For contributions to tutorial and guide-style documentation on [docs.scala-lang.org](http://docs.scala-lang.org), see the ["doc-site"'s contribution guide](http://docs.scala-lang.org/contribute.html). @@ -21,13 +21,13 @@ contribution steps and guidelines. Thank you.* Since API documentation is located in Scala source code files, the process for contributing API documentation is similar to that of contributing bug-fixes to the Scala code base, but without the requirement that there be an issue filed on JIRA -first. When forking/branching, just use a `scaladoc/xxxx` branch name, where xxxx is a +first. When forking/branching, just use a `scaladoc/xxxx` branch name, where xxxx is a descriptive, but short branch name (e.g. `scaladoc/future-object`). However, if an issue *does* exist, please use `issue/NNNN`, where NNNN is the ticket number, instead. If you would like to assist us by helping us find missing documentation and -submitting bug reports for existing documentation, +submitting bug reports for existing documentation, [please read the following section](#contribute-api-documentation-bug-reports). If you want to contribute new API documentation, [jump down to the next section](#contribute-new-api-documentation). @@ -35,9 +35,9 @@ If you want to contribute new API documentation, ## Contribute API Documentation Bug Reports One good way to contribute is by helping us to identify missing documentation. To do -this, [browse the current API documentationn](http://www.scala-lang.org/api/current/) -and identify missing, incorrect or inadequate documentation. A good place to start is -package objects for important packages (these often get overlooked for documentation +this, [browse the current API documentation](http://www.scala-lang.org/api/current/) +and identify missing, incorrect or inadequate documentation. A good place to start is +package objects for important packages (these often get overlooked for documentation and are a good place for API overviews). If you find an issue, please log it in the [Scala issue tracker](https://issues.scala-lang.org) From db2a14f159ab6db8c802cb415885cc1645cbcb85 Mon Sep 17 00:00:00 2001 From: JustinPihony Date: Tue, 3 Feb 2015 21:35:08 -0500 Subject: [PATCH 0059/3075] Add u to docmentation typo Review by @dickwall --- contribute/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contribute/index.md b/contribute/index.md index 9ea981b115..338ff06a06 100644 --- a/contribute/index.md +++ b/contribute/index.md @@ -20,7 +20,7 @@ how to efficiently report a bug. An easy but very important way to contribute to Scala is to [help with the guide/tutorial-style documentation on docs.scala-lang.org](http://docs.scala-lang.org/contribute.html). -If you want to [contribute to Scala standard library API docmentation](./scala-standard-library-api-documentation.html), the +If you want to [contribute to Scala standard library API documentation](./scala-standard-library-api-documentation.html), the process is slightly different, since API documentation lives within Scala standard library source code. ### Compiler and other tools From eb1e3cbd55fa0fb19c8f0f9eb444cd16527d4d15 Mon Sep 17 00:00:00 2001 From: Dick Wall Date: Mon, 9 Feb 2015 14:51:26 -0800 Subject: [PATCH 0060/3075] Update contributor pages for bugs/issues - provide issue checklist - Individual changes to docs: - corelibs.md and tools.md - add placeholders/call for help - documentation.md - small changes and spelling only - guide.md - bugfix checklist with links to other resources for each step - hacker-guide.md - spelling corrections - index.md - organize by type of contribution - scala-internals.md - new doc describing use of scala-internals for coordination - scala-standard-library-api-documentation.md - spelling/minor --- contribute/corelibs.md | 8 + contribute/documentation.md | 92 ++++++++---- contribute/guide.md | 137 ++++-------------- contribute/hacker-guide.md | 6 +- contribute/index.md | 67 +++++++-- contribute/scala-internals.md | 45 ++++++ ...cala-standard-library-api-documentation.md | 6 +- contribute/tools.md | 8 + 8 files changed, 213 insertions(+), 156 deletions(-) create mode 100644 contribute/corelibs.md create mode 100644 contribute/scala-internals.md create mode 100644 contribute/tools.md diff --git a/contribute/corelibs.md b/contribute/corelibs.md new file mode 100644 index 0000000000..1429ec87ff --- /dev/null +++ b/contribute/corelibs.md @@ -0,0 +1,8 @@ +--- +layout: page +title: Core Library Contributions +--- +## Under Construction + +If you would like to help complete this document, welcome, and please head over and read [Documentation Contributions](./documentation.html#the-scala-language-site), +and let us know on the [scala-internals](https://groups.google.com/forum/#!forum/scala-internals) forum (suggested post title: `[docs] Core Library Contributions`) so that we can get you hooked up with the right people. \ No newline at end of file diff --git a/contribute/documentation.md b/contribute/documentation.md index 05b2455a5f..da20b9360d 100644 --- a/contribute/documentation.md +++ b/contribute/documentation.md @@ -2,28 +2,70 @@ layout: page title: Documentation Contributions --- -# Contributing documentation to the Scala project - -TODO - - +## Contributing Documentation to the Scala project + +There are several ways you can help out with the improvement of Scala documentation. These include: + +* Code examples and tutorials in activator templates. +* The Scala Wiki +* API Documentation in Scaladoc +* Guides, Overviews, Tutorials, Cheat Sheets and more on the docs.scala-lang.org site +* Updating Documents on the Main Scala Language Site (this one) + +Please read this page, and the pages linked from this one, fully before contributing documentation. Many of the questions you have will be answered in these resources. If you have a question that isn't answered, feel free to ask on the [scala-internals Google group](https://groups.google.com/forum/#!forum/scala-internals) and then, please, submit a pull request with updated documentation reflecting that answer. + +**General requirements** for documentation submissions include spell-checking all written language, ensuring code samples compile and run correctly, correct grammar, and clean formatting/layout of the documentation. + +Thanks + +### Examples/Tutorials in Activator Templates + +[Typesafe Activator](https://typesafe.com/community/core-tools/activator-and-sbt) +is a tool based on SBT, with a UI mode that is ideal for code based tutorials, overviews and walk-throughs. To contribute an example in activator, you can fork an existing template, edit it, add a tutorial, upload it to github and then submit the github project into the template repository. It's the fastest way to produce a working code example with tutorial. + +Please see [Contributing an Activator Template](https://typesafe.com/activator/template/contribute) for more details. + +### API Documentation (Scaladoc) + +The Scala API documentation lives with the scala project source code. There are many ways you can help with improving Scaladoc, including: + +* [Log issues for missing scaladoc documentation](./scala-standard-library-api-documentation.html#contribute-api-documentation-bug-reports) - +Please *follow the issue submission process closely* to help prevent duplicate issues being created. +* [Claim Scaladoc Issues and Provide Documentation](./scala-standard-library-api-documentation.html) - please claim issues prior to working on a specific scaladoc task to prevent duplication of effort. If you sit on an issue for too long without submitting a pull request, it will revert back to unassigned and you will need to re-claim it. +* You can also just +[submit new Scaladoc](./scala-standard-library-api-documentation.html) +without creating an issue, but please look to see if there is an issue already submitted for your task and claim it if there is. If not, please post your intention to work on a specific scaladoc task on scala-internals so that people know what you are doing. + +### The Scala Wiki + +The [Scala wiki](https://wiki.scala-lang.org/) could be a useful resource, but tends to get out of date quickly. It is perhaps best viewed as a place for information to temporarily live while it is constructed and refined, but with an aim to putting the material into the [docs.scala-lang.org](http://docs.scala-lang.org) site eventually (see the next section). Nonetheless, it is a fast way to add some public documentation. + +The wiki is self documenting, so make sure to take a look at the [home page](https://wiki.scala-lang.org/) to get started. Please consider contributions to [docs.scala-lang.org](docs.scala-lang.org) for more enduring documentation, even though it is more work to get through the review process for the main doc site. + +### The Main Scala Documentation Site + +[docs.scala-lang.org](https://wiki.scala-lang.org/) houses the primary source of written, non-API documentation for Scala. It's a github project that you can fork and submit pull requests from. It includes: + +* Overviews +* Tutorials +* Conversion Guides from Other Languages +* Cheat Sheets +* A Glossary +* The Scala Style Guide +* The Scala Language Specification +* SIP (Scala Improvement Process) Proposals +and more + +Please read [contributing to the docs.scala-lang.org site](http://docs.scala-lang.org/contribute.html) through before embarking on changes. The site uses +the [Jekyll](http://jekyllrb.com/) markdown engine so you will need to follow the instructions to get that running as well. + +### The Scala Language Site + +Additional high-level documentation (including documentation on contributing +to Scala and related projects) is provided on the main +[Scala Language site](http://scala-lang.org), and is also kept in the +[scala-lang github project](https://github.com/scala/scala-lang) which may be forked to create pull requests. + +Please read both the +[docs.scala-lang.org contribution](http://docs.scala-lang.org/contribute.html) document and the scala-lang.org github README file before embarking on any changes to the Scala language site, as it uses the same Jekyll markdown tool and many of the same conventions as the Scala documentation site. + diff --git a/contribute/guide.md b/contribute/guide.md index 9446e6ce9c..809c6558d5 100644 --- a/contribute/guide.md +++ b/contribute/guide.md @@ -1,5 +1,5 @@ --- -layout: page-full-width +layout: page title: Contributing guide --- @@ -13,10 +13,6 @@ title: Contributing guide

Report an issue

File a bug report or a feature request.

-
-

Documentation

-

Improve the documentation itself.

-
@@ -28,10 +24,6 @@ title: Contributing guide

Hacker's guide

Learn to write good code and improve your chances of contributing to the Scala galaxy.

-
-

Hall of Fame

-

Track your rockstar status in the community.

-