From 37b0ab6a318027e970e3c9a7bea01513e7cba124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9A=D0=BE=D1=80=D1=81?= =?UTF-8?q?=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Thu, 5 Oct 2023 09:40:16 +0300 Subject: [PATCH 1/6] Update index.md in russian --- _ru/index.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/_ru/index.md b/_ru/index.md index 3a3cf3a918..df628955a5 100644 --- a/_ru/index.md +++ b/_ru/index.md @@ -19,7 +19,11 @@ sections: - title: "Книга по Scala 3" description: "Изучайте Scala используя серию коротких уроков." icon: "fa fa-book-open" - link: /scala3/book/introduction.html + link: /ru/scala3/book/introduction.html + - title: "Набор инструментов Scala" + description: "Отправка HTTP-запросов, запись файлов, запуск программ, обработка JSON..." + icon: "fa fa-toolbox" + link: /toolkit/introduction.html - title: Онлайн Курсы, Упражнения и Блоги description: "Обучающие курсы по Scala от новичка до продвинутого уровня." icon: "fa fa-cloud" @@ -55,10 +59,14 @@ sections: description: "Список по наиболее часто задаваемым вопросам с ответами по функционалу Scala." icon: "fa fa-question-circle" link: /tutorials/FAQ/index.html - - title: "Спецификация" - description: "Официальная спецификация языка Scala." + - title: "Спецификация v2.x" + description: "Официальная спецификация языка Scala 2." icon: "fa fa-book" link: https://scala-lang.org/files/archive/spec/2.13/ + - title: "Спецификация v3.x" + description: "Официальная спецификация языка Scala 3." + icon: "fa fa-book" + link: https://scala-lang.org/files/archive/spec/3.4/ - title: "Справочник по языку Scala 3" description: "Справочник по языку Scala 3." icon: "fa fa-book" @@ -73,15 +81,15 @@ sections: - title: "Новое в Scala 3" description: "Обзор новой функциональности в Scala 3." icon: "fa fa-star" - link: /scala3/new-in-scala3.html + link: /ru/scala3/new-in-scala3.html - title: "Новая функциональность Scaladoc для Scala 3" description: "Ключевые особенности новой функциональности Scaladoc." icon: "fa fa-star" - link: /scala3/scaladoc.html + link: /ru/scala3/scaladoc.html - title: "Выступления" description: "Доступные онлайн выступления о Scala 3." icon: "fa fa-play-circle" - link: /scala3/talks.html + link: /ru/scala3/talks.html - title: "Развитие Scala" links: From 2cac84a05f00dab552b7da95bb9c63643c2ee9da Mon Sep 17 00:00:00 2001 From: Volodymyr Myroniuk Date: Fri, 6 Oct 2023 17:36:05 +0300 Subject: [PATCH 2/6] Fix code in 'Scala Tour / Singleton Objects / Companion Objects' --- _tour/singleton-objects.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/_tour/singleton-objects.md b/_tour/singleton-objects.md index 369402eee1..fb985d4a17 100644 --- a/_tour/singleton-objects.md +++ b/_tour/singleton-objects.md @@ -104,6 +104,7 @@ An object with the same name as a class is called a _companion object_. Converse {% tab 'Scala 2' for=companion-object-circle %} ```scala +import scala.math.Pi import scala.math.pow case class Circle(radius: Double) { @@ -123,7 +124,7 @@ circle1.area {% tab 'Scala 3' for=companion-object-circle %} ```scala -import scala.math.pow +import scala.math.{Pi, pow} case class Circle(radius: Double): import Circle.* From 0c0907320a16839d5bbef5b6613c8da31ab28995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9A=D0=BE=D1=80=D1=81?= =?UTF-8?q?=D0=B0=D0=BA=D0=BE=D0=B2?= Date: Fri, 6 Oct 2023 19:58:51 +0300 Subject: [PATCH 3/6] Add concurrency.md in russian --- _overviews/scala3-book/concurrency.md | 2 +- _overviews/scala3-book/scala-tools.md | 2 +- _ru/scala3/book/ca-summary.md | 2 +- _ru/scala3/book/concurrency.md | 333 ++++++++++++++++++++++++++ _ru/scala3/book/scala-tools.md | 18 ++ 5 files changed, 354 insertions(+), 3 deletions(-) create mode 100644 _ru/scala3/book/concurrency.md create mode 100644 _ru/scala3/book/scala-tools.md diff --git a/_overviews/scala3-book/concurrency.md b/_overviews/scala3-book/concurrency.md index 6740910c4a..ef89e0a822 100644 --- a/_overviews/scala3-book/concurrency.md +++ b/_overviews/scala3-book/concurrency.md @@ -2,7 +2,7 @@ title: Concurrency type: chapter description: This page discusses how Scala concurrency works, with an emphasis on Scala Futures. -languages: [zh-cn] +languages: [ru, zh-cn] num: 68 previous-page: ca-summary next-page: scala-tools diff --git a/_overviews/scala3-book/scala-tools.md b/_overviews/scala3-book/scala-tools.md index 1b6badd809..7d6bb7a397 100644 --- a/_overviews/scala3-book/scala-tools.md +++ b/_overviews/scala3-book/scala-tools.md @@ -2,7 +2,7 @@ title: Scala Tools type: chapter description: This chapter looks at two commonly-used Scala tools, sbt and ScalaTest. -languages: [zh-cn] +languages: [ru, zh-cn] num: 69 previous-page: concurrency next-page: tools-sbt diff --git a/_ru/scala3/book/ca-summary.md b/_ru/scala3/book/ca-summary.md index 3c56a29139..f3b68b7211 100644 --- a/_ru/scala3/book/ca-summary.md +++ b/_ru/scala3/book/ca-summary.md @@ -9,7 +9,7 @@ description: На этой странице представлен кратки language: ru num: 67 previous-page: ca-implicit-conversions -next-page: +next-page: concurrency --- В этой главе представлено введение в большинство тем контекстных абстракций, в том числе: diff --git a/_ru/scala3/book/concurrency.md b/_ru/scala3/book/concurrency.md new file mode 100644 index 0000000000..ec43810bfa --- /dev/null +++ b/_ru/scala3/book/concurrency.md @@ -0,0 +1,333 @@ +--- +layout: multipage-overview +title: Параллелизм +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: chapter +description: На этой странице обсуждается, как работает параллелизм в Scala, с упором на Scala Futures. +language: ru +num: 68 +previous-page: ca-summary +next-page: scala-tools +--- + +Для написания параллельных приложений на Scala, _можно_ использовать нативный Java `Thread`, +но Scala [Future](https://www.scala-lang.org/api/current/scala/concurrent/Future$.html) предлагает более высокоуровневый +и идиоматический подход, поэтому он предпочтителен и рассматривается в этой главе. + +## Введение + +Вот описание Scala `Future` из его Scaladoc: + +> "`Future` представляет собой значение, которое может быть или не быть доступным _в настоящее время_, +> но будет доступно в какой-то момент, или вызовет исключение, если это значение не может быть сделано доступным". + +Чтобы продемонстрировать, что это значит, сначала рассмотрим однопоточное программирование. +В однопоточном мире результат вызова метода привязывается к переменной следующим образом: + +```scala +def aShortRunningTask(): Int = 42 +val x = aShortRunningTask() +``` + +В этом коде значение `42` сразу привязывается к `x`. + +При работе с `Future` процесс назначения выглядит примерно так: + +```scala +def aLongRunningTask(): Future[Int] = ??? +val x = aLongRunningTask() +``` + +Но главное отличие в этом случае заключается в том, что, поскольку `aLongRunningTask` возвращает неопределенное время, +значение `x` может быть доступно или недоступно _в данный момент_, но оно будет доступно в какой-то момент — в будущем. + +Другой способ взглянуть на это с точки зрения блокировки. +В этом однопоточном примере оператор `println` не печатается до тех пор, пока не завершится выполнение `aShortRunningTask`: + +```scala +def aShortRunningTask(): Int = + Thread.sleep(500) + 42 +val x = aShortRunningTask() +println("Here") +``` + +И наоборот, если `aShortRunningTask` создается как `Future`, оператор `println` печатается почти сразу, +потому что `aShortRunningTask` порождается в другом потоке — он не блокируется. + +В этой главе будет рассказано, как использовать `Future`, +в том числе как запускать несколько `Future` параллельно и объединять их результаты в выражении `for`. +Также будут показаны примеры методов, которые используются для обработки значения `Future` после его возврата. + +> О `Future`, важно знать, что они задуманы как одноразовая конструкция +> "Обработайте это относительно медленное вычисление в каком-нибудь другом потоке и верните мне результат, когда закончите". +> В отличие от этого, акторы [Akka](https://akka.io) предназначены для работы в течение длительного времени +> и отвечают на множество запросов в течение своей жизни. +> В то время как субъект может жить вечно, `Future` в конечном итоге содержит результат вычисления, +> которое выполнялось только один раз. + +## Пример в REPL + +`Future` используется для создания временного кармана параллелизма. +Например, можно использовать `Future`, когда нужно вызвать алгоритм, +который выполняется неопределенное количество времени — например, вызов удаленного микросервиса, — +поэтому его желательно запустить вне основного потока. + +Чтобы продемонстрировать, как это работает, начнем с примера `Future` в REPL. +Во-первых, вставим необходимые инструкции импорта: + +```scala +import scala.concurrent.Future +import scala.concurrent.ExecutionContext.Implicits.global +import scala.util.{Failure, Success} +``` + +Теперь можно создать `Future`. +Для этого примера сначала определим долговременный однопоточный алгоритм: + +```scala +def longRunningAlgorithm() = + Thread.sleep(10_000) + 42 +``` + +Этот причудливый алгоритм возвращает целочисленное значение `42` после десятисекундной задержки. +Теперь вызовем этот алгоритм, поместив его в конструктор `Future` и присвоив результат переменной: + +```scala +scala> val eventualInt = Future(longRunningAlgorithm()) +eventualInt: scala.concurrent.Future[Int] = Future() +``` + +Вычисления начинают выполняться после вызова `longRunningAlgorithm()`. +Если сразу проверить значение переменной `eventualInt`, то можно увидеть, что `Future` еще не завершен: + +```scala +scala> eventualInt +val res1: scala.concurrent.Future[Int] = Future() +``` + +Но если проверить через десять секунд ещё раз, то можно увидеть, что оно выполнено успешно: + +```scala +scala> eventualInt +val res2: scala.concurrent.Future[Int] = Future(Success(42)) +``` + +Хотя это относительно простой пример, он демонстрирует основной подход: +просто создайте новое `Future` с помощью своего долговременного алгоритма. + +Одна вещь, на которую следует обратить внимание - +это то, что ожидаемый результат `42` обернут в `Success`, который обернут в `Future`. +Это ключевая концепция для понимания: значение `Future` всегда является экземпляром одного из `scala.util.Try`: `Success` или `Failure`. +Поэтому, при работе с результатом `Future`, используются обычные методы обработки `Try`. + +### Использование `map` с `Future` + +`Future` содержит метод `map`, который используется точно так же, как метод `map` для коллекций. +Вот как выглядит результат, при вызове `map` сразу после создания переменной `a`: + +```scala +scala> val a = Future(longRunningAlgorithm()).map(_ * 2) +a: scala.concurrent.Future[Int] = Future() +``` + +Как показано, для `Future`, созданного с помощью `longRunningAlgorithm`, первоначальный вывод показывает `Future()`. +Но если проверить значение `a` через десять секунд, то можно увидеть, что оно содержит ожидаемый результат `84`: + +```scala +scala> a +res1: scala.concurrent.Future[Int] = Future(Success(84)) +``` + +Еще раз, успешный результат обернут внутри `Success` и `Future`. + +### Использование методов обратного вызова с `Future` + +В дополнение к функциям высшего порядка, таким как `map`, с `Future` также можно использовать методы обратного вызова. +Одним из часто используемых методов обратного вызова является `onComplete`, принимающий _частично определенную функцию_, +в которой обрабатываются случаи `Success` и `Failure`: + +```scala +Future(longRunningAlgorithm()).onComplete { + case Success(value) => println(s"Got the callback, value = $value") + case Failure(e) => e.printStackTrace +} +``` + +Если вставить этот код в REPL, то в конечном итоге придет результат: + +```scala +Got the callback, value = 42 +``` + +## Другие методы `Future` + +Класс `Future` содержит некоторые методы, которые можно найти в классах коллекций Scala, в том числе: + +- `filter` +- `flatMap` +- `map` + +Методы обратного вызова: + +- `onComplete` +- `andThen` +- `foreach` + +Другие методы трансформации: + +- `fallbackTo` +- `recover` +- `recoverWith` + +См. страницу [Futures and Promises][futures] для обсуждения дополнительных методов, доступных для `Future`. + +## Запуск нескольких `Future` и объединение результатов + +Чтобы запустить несколько вычислений параллельно и соединить их результаты после завершения всех `Future`, +можно использовать выражение `for`. + +Правильный подход такой: + +1. Запустить вычисления, которые возвращают `Future` результаты +2. Объединить их результаты в выражении `for` +3. Извлечь объединенный результат, используя `onComplete` или аналогичный метод + +### Пример + +Три шага правильного подхода показаны в следующем примере. +Ключевой момент - сначала запускаются вычисления, возвращающие `Future`, а затем они объединяются в выражении `for`: + +```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 +def sleep(millis: Long) = Thread.sleep(millis) + +@main def multipleFutures1 = + + println(s"creating the futures: ${delta()}") + + // (1) запуск вычислений, возвращающих Future + val f1 = Future { sleep(800); 1 } // в конце концов возвращается 1 + val f2 = Future { sleep(200); 2 } // в конце концов возвращается 2 + val f3 = Future { sleep(400); 3 } // в конце концов возвращается 3 + + // (2) объединение нескольких Future в выражении `for` + val result = + for + r1 <- f1 + r2 <- f2 + r3 <- f3 + yield + println(s"in the 'yield': ${delta()}") + (r1 + r2 + r3) + + // (3) обработка результата + result.onComplete { + case Success(x) => + println(s"in the Success case: ${delta()}") + println(s"result = $x") + case Failure(e) => + e.printStackTrace + } + + println(s"before the 'sleep(3000)': ${delta()}") + + // важно для небольшой параллельной демонстрации: не глушить jvm + sleep(3000) +``` + +После запуска этого приложения, вывод выглядит следующим образом: + +``` +creating the futures: 1 +before the 'sleep(3000)': 2 +in the 'yield': 806 +in the Success case: 806 +result = 6 +``` + +Как показывает вывод, `Future` создаются очень быстро, +и всего за две миллисекунды достигается оператор печати непосредственно перед операцией `sleep(3000)` в конце метода. +Весь этот код выполняется в основном потоке JVM. Затем, через 806 мс, три `Future` завершаются, и выполняется код в блоке `yield`. +Затем код немедленно переходит к варианту `Success` в методе `onComplete`. + +Вывод 806 мс является ключом к тому, чтобы убедиться, что три вычисления выполняются параллельно. +Если бы они выполнялись последовательно, общее время составило бы около 1400 мс — сумма времени ожидания трех вычислений. +Но поскольку они выполняются параллельно, общее время чуть больше, чем у самого продолжительного вычисления `f1`, +которое составляет 800 мс. + +> Обратите внимание, что если бы вычисления выполнялись в выражении `for`, +> они выполнялись бы последовательно, а не параллельно: +> +> ``` +> // последовательное выполнение (без параллелизма!) +> for +> r1 <- Future { sleep(800); 1 } +> r2 <- Future { sleep(200); 2 } +> r3 <- Future { sleep(400); 3 } +> yield +> r1 + r2 + r3 +> ``` +> +> Итак, если необходимо, чтобы вычисления выполнялись параллельно, не забудьте запустить их вне выражения `for`. + +### Метод, возвращающий Future + +Было показано, как передавать однопоточный алгоритм в конструктор `Future`. +Ту же технику можно использовать для создания метода, который возвращает `Future`: + +```scala +// моделируем медленно работающий метод +def slowlyDouble(x: Int, delay: Long): Future[Int] = Future { + sleep(delay) + x * 2 +} +``` + +Как и в предыдущих примерах, достаточно просто присвоить результат вызова метода новой переменной. +Тогда, если сразу проверить результат, то можно увидеть, что он не завершен, +но по истечении времени задержки в `Future` результат будет выдан: + +``` +scala> val f = slowlyDouble(2, 5_000L) +val f: concurrent.Future[Int] = Future() + +scala> f +val res0: concurrent.Future[Int] = Future() + +scala> f +val res1: concurrent.Future[Int] = Future(Success(4)) +``` + +## Ключевые моменты о Future + +Надеюсь, эти примеры дадут вам представление о том, как работает Scala `Future`. +Подводя итог, несколько ключевых моментов о `Future`: + +- `Future` создается для запуска задач вне основного потока +- `Future` предназначены для одноразовых, потенциально длительных параллельных задач, которые _в конечном итоге_ возвращают значение; + они создают временный карман параллелизма +- `Future` начинает работать в момент построения +- преимущество `Future` над потоками заключается в том, что они работают с выражениями `for` + и имеют множество методов обратного вызова, упрощающих процесс работы с параллельными потоками +- при работе с `Future` не нужно беспокоиться о низкоуровневых деталях управления потоками +- результат `Future` обрабатывается с помощью методов обратного вызова, таких как `onComplete` и `andThen`, + или методов преобразования, таких как `filter`, `map` и т.д. +- значение внутри `Future` всегда является экземпляром одного из типов `Try`: `Success` или `Failure` +- при использовании нескольких `Future` для получения одного результата, они объединяются в выражении `for` + +Кроме того, как было видно по операторам `import`, Scala `Future` зависит от `ExecutionContext`. + +Дополнительные сведения о `Future` см. в статье [Futures and Promises][futures], +в которой обсуждаются futures, promises и execution contexts. +В ней также обсуждается, как выражение `for` транслируется в операцию `flatMap`. + +[futures]: {% link _overviews/core/futures.md %} diff --git a/_ru/scala3/book/scala-tools.md b/_ru/scala3/book/scala-tools.md new file mode 100644 index 0000000000..640a67995d --- /dev/null +++ b/_ru/scala3/book/scala-tools.md @@ -0,0 +1,18 @@ +--- +layout: multipage-overview +title: Scala утилиты +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: chapter +description: В этой главе рассматриваются два широко используемых инструмента Scala sbt и ScalaTest. +language: ru +num: 69 +previous-page: concurrency +next-page: +--- + +В этой главе представлены два способа написания и запуска программ в Scala: + +- создавая Scala проекты, возможно, содержащие несколько файлов, и определяя точку входа в программу, +- путем взаимодействия с worksheet, который представляет собой программу, определенную в одном файле и выполняемую построчно. From 8a7f1b7c97e2a83a1ec58f6813a3d78dc2378276 Mon Sep 17 00:00:00 2001 From: Volodymyr Myroniuk Date: Fri, 6 Oct 2023 20:11:08 +0300 Subject: [PATCH 4/6] Make the imports in the same style for Scala 2 and 3 --- _tour/singleton-objects.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/_tour/singleton-objects.md b/_tour/singleton-objects.md index fb985d4a17..47a67ee175 100644 --- a/_tour/singleton-objects.md +++ b/_tour/singleton-objects.md @@ -104,8 +104,7 @@ An object with the same name as a class is called a _companion object_. Converse {% tab 'Scala 2' for=companion-object-circle %} ```scala -import scala.math.Pi -import scala.math.pow +import scala.math.{Pi, pow} case class Circle(radius: Double) { import Circle._ From 472932a339d4b5600cd45b6e55dc5f0e72631720 Mon Sep 17 00:00:00 2001 From: John Duffell Date: Tue, 10 Oct 2023 08:56:52 +0100 Subject: [PATCH 5/6] fix typo and bump scala 2.13 version --- _overviews/scala3-migration/tutorial-macro-mixing.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/_overviews/scala3-migration/tutorial-macro-mixing.md b/_overviews/scala3-migration/tutorial-macro-mixing.md index e7684adc7b..a0a88b17ce 100644 --- a/_overviews/scala3-migration/tutorial-macro-mixing.md +++ b/_overviews/scala3-migration/tutorial-macro-mixing.md @@ -106,8 +106,8 @@ lazy val example = project.in(file("example")) lazy val `example-compat` = project.in(file("example-compat")) .settings( - scalaVersion := "2.13.11", - libraryDependency += "org.scala-lang" % "scala-reflect" % scalaVersion.value + scalaVersion := "2.13.12", + libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value ) ``` @@ -151,7 +151,7 @@ Since we want to execute the tests in Scala 2.13 and Scala 3, we create a cross- lazy val `example-test` = project.in(file("example-test")) .settings( scalaVersion := "3.3.1", - crossScalaVersions := Seq("3.3.1", "2.13.11"), + crossScalaVersions := Seq("3.3.1", "2.13.12"), scalacOptions ++= { CrossVersion.partialVersion(scalaVersion.value) match { case Some((2, 13)) => Seq("-Ytasty-reader") @@ -185,7 +185,7 @@ class MacrosSpec extends munit.FunSuite { You should now be able to run the tests in both versions. {% highlight text %} -sbt:example> ++2.13.11 +sbt:example> ++2.13.12 sbt:example> example-test / test location.MacrosSpec: + location @@ -213,7 +213,7 @@ You are now ready to publish your library. It can be used in Scala 3 projects, or in Scala 2.13 projects with these settings: ```scala -scalaVersion := "2.13.11" +scalaVersion := "2.13.12" libraryDependencies += ("org" %% "example" % "x.y.z").cross(CrossVersion.for2_13Use3) scalacOptions += "-Ytasty-reader" ``` From a1fa41281936a0ac6b989558758d12d093a89b05 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Sun, 15 Oct 2023 19:31:08 -0600 Subject: [PATCH 6/6] fix Scala Native 404 links --- _overviews/jdk-compatibility/overview.md | 2 +- _overviews/scala3-book/scala-for-javascript-devs.md | 2 +- _overviews/scala3-book/scala-for-python-devs.md | 2 +- _overviews/scala3-migration/tutorial-prerequisites.md | 2 +- _zh-cn/overviews/scala3-book/scala-for-javascript-devs.md | 2 +- _zh-cn/overviews/scala3-book/scala-for-python-devs.md | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/_overviews/jdk-compatibility/overview.md b/_overviews/jdk-compatibility/overview.md index fdcde855dc..230e1a1c14 100644 --- a/_overviews/jdk-compatibility/overview.md +++ b/_overviews/jdk-compatibility/overview.md @@ -4,7 +4,7 @@ title: JDK Compatibility permalink: /overviews/jdk-compatibility/overview.html --- -Scala's primary platform is the Java Virtual Machine (JVM). (Other supported platforms: [Scala.js](https://www.scala-js.org/), [Scala Native](https://scala-native.readthedocs.io/).) +Scala's primary platform is the Java Virtual Machine (JVM). (Other supported platforms: [Scala.js](https://www.scala-js.org/), [Scala Native](https://scala-native.org/).) Sometimes new JVM and JDK (Java Development Kit) versions require us to update Scala to remain compatible. diff --git a/_overviews/scala3-book/scala-for-javascript-devs.md b/_overviews/scala3-book/scala-for-javascript-devs.md index 213b1bada7..658b2a6539 100644 --- a/_overviews/scala3-book/scala-for-javascript-devs.md +++ b/_overviews/scala3-book/scala-for-javascript-devs.md @@ -51,7 +51,7 @@ Also at a high level, some of the differences between JavaScript and Scala are: - As a pure OOP language and a pure FP language, Scala encourages a fusion of OOP and FP, with functions for the logic and immutable objects for modularity - Scala has state of the art, third-party, open source functional programming libraries - Everything in Scala is an _expression_: constructs like `if` statements, `for` loops, `match` expressions, and even `try`/`catch` expressions all have return values -- The [Scala Native](https://scala-native.readthedocs.io/en/v0.3.9-docs) project lets you write “systems” level code, and also compiles to native executables +- The [Scala Native](https://scala-native.org/) project lets you write “systems” level code, and also compiles to native executables ### Programming level differences diff --git a/_overviews/scala3-book/scala-for-python-devs.md b/_overviews/scala3-book/scala-for-python-devs.md index d55e6ed619..5b0e8dec91 100644 --- a/_overviews/scala3-book/scala-for-python-devs.md +++ b/_overviews/scala3-book/scala-for-python-devs.md @@ -54,7 +54,7 @@ Also at a high level, the _differences_ between Python and Scala are: - Though it’s statically typed, Scala features like type inference make it feel like a dynamic language - Python is interpreted, and Scala code is compiled to _.class_ files, and runs on the Java Virtual Machine (JVM) - 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](https://scala-native.readthedocs.io/en/v0.3.9-docs) project lets you write “systems” level code, and compiles to native executables +- The [Scala Native](https://scala-native.org/) project lets you write “systems” level code, and compiles to native executables - 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 variables and immutable collections - Scala has excellent support for [concurrent and parallel programming][concurrency] diff --git a/_overviews/scala3-migration/tutorial-prerequisites.md b/_overviews/scala3-migration/tutorial-prerequisites.md index cdd96da785..dabb242834 100644 --- a/_overviews/scala3-migration/tutorial-prerequisites.md +++ b/_overviews/scala3-migration/tutorial-prerequisites.md @@ -101,7 +101,7 @@ addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.5.0") ### Scala Native -Scala 3 is now supported in Scala Native starting with [v0.4.3](https://scala-native.readthedocs.io/en/latest/changelog/0.4.3.html) +Scala 3 is supported in [Scala Native](https://scala-native.org/) since v0.4.3. The minimal version of Scala 3 supported by Scala Native is 3.1.0, due to fatal blockers in Scala 3.0.x diff --git a/_zh-cn/overviews/scala3-book/scala-for-javascript-devs.md b/_zh-cn/overviews/scala3-book/scala-for-javascript-devs.md index e7a74b8757..c94405f479 100644 --- a/_zh-cn/overviews/scala3-book/scala-for-javascript-devs.md +++ b/_zh-cn/overviews/scala3-book/scala-for-javascript-devs.md @@ -54,7 +54,7 @@ permalink: "/zh-cn/scala3/book/:title.html" - 作为一种纯 OOP 语言和纯 FP 语言,Scala 鼓励 OOP 和 FP 的融合,具有用于逻辑的函数和用于模块化的不可变对象 - Scala 拥有最先进的第三方开源函数式编程库 - Scala 中的一切都是一个_表达式_:像 `if` 语句、`for` 循环、`match` 表达式,甚至 `try`/`catch` 表达式都有返回值 -- [Scala Native](https://scala-native.readthedocs.io/en/v0.3.9-docs) 项目让您可以编写“系统”级代码,也可以编译为本机可执行文件 +- [Scala Native](https://scala-native.org/) 项目让您可以编写“系统”级代码,也可以编译为本机可执行文件 ### 编程层次差异 diff --git a/_zh-cn/overviews/scala3-book/scala-for-python-devs.md b/_zh-cn/overviews/scala3-book/scala-for-python-devs.md index 2ea3bacf3d..fe53fd6b15 100644 --- a/_zh-cn/overviews/scala3-book/scala-for-python-devs.md +++ b/_zh-cn/overviews/scala3-book/scala-for-python-devs.md @@ -58,7 +58,7 @@ TODO: We should probably go through this document and add links to our other det - 虽然它是静态类型的,但 Scala 的类型推断等特性让它感觉像是一门动态语言 - Python 被解释,Scala 代码被编译成 _.class_ 文件,并在 Java 虚拟机 (JVM) 上运行 - 除了在 JVM 上运行之外,[Scala.js](https://www.scala-js.org) 项目允许您使用 Scala 作为 JavaScript 替代品 -- [Scala Native](https://scala-native.readthedocs.io/en/v0.3.9-docs) 项目可让您编写“系统”级代码,并编译为本机可执行文件 +- [Scala Native](https://scala-native.org/) 项目可让您编写“系统”级代码,并编译为本机可执行文件 - Scala 中的一切都是一个_表达式_:像 `if` 语句、`for` 循环、`match` 表达式,甚至 `try`/`catch` 表达式都有返回值 - Scala 习惯默认不变性:鼓励您使用不可变变量和不可变集合 - Scala 对[并发和并行编程][concurrency]有很好的支持