From f4045ffe0ea4be27100c3a52ed4ae49f0927395d 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, 14 Jul 2023 22:19:46 +0300 Subject: [PATCH 1/3] Add ca-contextual-abstractions-intro.md in russian --- .../ca-contextual-abstractions-intro.md | 2 +- .../scala3-book/ca-extension-methods.md | 2 +- .../book/ca-contextual-abstractions-intro.md | 96 ++++++++++++ _ru/scala3/book/ca-extension-methods.md | 145 ++++++++++++++++++ _ru/scala3/book/types-others.md | 2 +- 5 files changed, 244 insertions(+), 3 deletions(-) create mode 100644 _ru/scala3/book/ca-contextual-abstractions-intro.md create mode 100644 _ru/scala3/book/ca-extension-methods.md diff --git a/_overviews/scala3-book/ca-contextual-abstractions-intro.md b/_overviews/scala3-book/ca-contextual-abstractions-intro.md index 33c10dd6cb..c6ec74ec17 100644 --- a/_overviews/scala3-book/ca-contextual-abstractions-intro.md +++ b/_overviews/scala3-book/ca-contextual-abstractions-intro.md @@ -2,7 +2,7 @@ title: Contextual Abstractions type: chapter description: This chapter provides an introduction to the Scala 3 concept of Contextual Abstractions. -languages: [zh-cn] +languages: [ru, zh-cn] num: 59 previous-page: types-others next-page: ca-extension-methods diff --git a/_overviews/scala3-book/ca-extension-methods.md b/_overviews/scala3-book/ca-extension-methods.md index 65b30183f4..9f54297f94 100644 --- a/_overviews/scala3-book/ca-extension-methods.md +++ b/_overviews/scala3-book/ca-extension-methods.md @@ -2,7 +2,7 @@ title: Extension Methods type: section description: This page demonstrates how Extension Methods work in Scala 3. -languages: [zh-cn] +languages: [ru, zh-cn] num: 60 previous-page: ca-contextual-abstractions-intro next-page: ca-context-parameters diff --git a/_ru/scala3/book/ca-contextual-abstractions-intro.md b/_ru/scala3/book/ca-contextual-abstractions-intro.md new file mode 100644 index 0000000000..eef3910c30 --- /dev/null +++ b/_ru/scala3/book/ca-contextual-abstractions-intro.md @@ -0,0 +1,96 @@ +--- +layout: multipage-overview +title: Контекстные абстракции +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: chapter +description: В этой главе представлено введение в концепцию контекстных абстракций Scala 3. +language: ru +num: 59 +previous-page: types-others +next-page: ca-extension-methods +--- + +## Предпосылка + +Контекстные абстракции — это способ абстрагироваться от контекста. +Они представляют собой единую парадигму с большим разнообразием вариантов использования, среди которых: + +- реализация тайп классов (_type classes_) +- установление контекста +- внедрение зависимости (_dependency injection_) +- выражение возможностей +- вычисление новых типов и доказательство взаимосвязей между ними + +В этом отношении Scala оказала влияние на другие языки. Например, трейты в Rust или protocol extensions Swift. +Предложения по дизайну также представлены для Kotlin в качестве разрешения зависимостей во время компиляции, +для C# в качестве Shapes и Extensions или для F# в качестве Traits. +Контекстные абстракции также являются общей особенностью средств доказательства теорем, таких как Coq или Agda. + +Несмотря на то, что в этих проектах используется разная терминология, +все они являются вариантами основной идеи вывода терминов (term inference): +учитывая тип, компилятор синтезирует "канонический" термин, который имеет этот тип. + +## Редизайн в Scala 3 + +В Scala 2 контекстные абстракции поддерживаются пометкой `implicit` определений (методов и значений) или параметров +(см. [Параметры контекста]({% link _overviews/scala3-book/ca-context-parameters.md %})). + +Scala 3 включает в себя переработку контекстных абстракций. +Хотя эти концепции постепенно "открывались" в Scala 2, теперь они хорошо известны и понятны, и редизайн использует эти знания. + +Дизайн Scala 3 фокусируется на **намерении**, а не на **механизме**. +Вместо того, чтобы предлагать одну очень мощную функцию имплицитов, +Scala 3 предлагает несколько функций, ориентированных на варианты использования: + +- **Расширение классов задним числом**. + В Scala 2 методы расширения должны были кодироваться с использованием [неявных преобразований][implicit-conversions] или [неявных классов]({% link _overviews/core/implicit-classes.md %}). + Напротив, в Scala 3 [методы расширения][extension-methods] теперь встроены непосредственно в язык, что приводит к улучшению сообщений об ошибках и улучшению вывода типов. + +- **Абстрагирование контекстной информации**. + [Предложения Using][givens] позволяют программистам абстрагироваться от информации, + которая доступна в контексте вызова и должна передаваться неявно. + В качестве улучшения по сравнению со Scala 2 подразумевается, что предложения using могут быть указаны по типу, + освобождая сигнатуры функций от имен переменных, на которые никогда не ссылаются явно. + +- **Предоставление экземпляров тайп-классов**. + [Given экземпляры][givens] позволяют программистам определять _каноническое значение_ определенного типа. + Это делает программирование с [тайп-классами][type-classes] более простым без утечек деталей реализации. + +- **Неявное преобразование одного типа в другой**. + Неявное преобразование было [переработано с нуля][implicit-conversions] как экземпляры тайп-класса `Conversion`. + +- **Контекстные абстракции высшего порядка**. + _Совершенно новая_ функция [контекстных функций][contextual-functions] делает контекстные абстракции объектами первого класса. + Они являются важным инструментом для авторов библиотек и позволяют выражать лаконичный DSL. + +- **Полезная обратная связь от компилятора**. + Если компилятор не может разрешить неявный параметр, теперь он предлагает [предложения по импорту](https://www.scala-lang.org/blog/2020/05/05/scala-3-import-suggestions.html), которые могут решить проблему. + +## Преимущества + +Эти изменения в Scala 3 обеспечивают лучшее разделение вывода терминов от остального языка: + +- существует единственный способ определить данные +- существует единственный способ ввести неявные параметры и аргументы +- существует отдельный способ [импорта givens][given-imports], который не позволяет им прятаться в море обычного импорта +- существует единственный способ определить [неявное преобразование][implicit-conversions], которое четко обозначено как таковое и не требует специального синтаксиса + +К преимуществам этих изменений относятся: + +- новый дизайн позволяет избежать взаимодействия функций и делает язык более согласованным +- implicits становятся более легкими для изучения и более сложными для злоупотреблений +- значительно улучшается ясность 95% программ Scala, использующих implicits +- есть потенциал, чтобы сделать вывод термов однозначным способом, который также доступен и удобен. + +В этой главе в следующих разделах представлены многие из этих новых функций. + +[givens]: {% link _overviews/scala3-book/ca-context-parameters.md %} +[given-imports]: {% link _overviews/scala3-book/ca-given-imports.md %} +[implicit-conversions]: {% link _overviews/scala3-book/ca-implicit-conversions.md %} +[extension-methods]: {% link _overviews/scala3-book/ca-extension-methods.md %} +[context-bounds]: {% link _overviews/scala3-book/ca-context-bounds.md %} +[type-classes]: {% link _overviews/scala3-book/ca-type-classes.md %} +[equality]: {% link _overviews/scala3-book/ca-multiversal-equality.md %} +[contextual-functions]: {{ site.scala3ref }}/contextual/context-functions.html diff --git a/_ru/scala3/book/ca-extension-methods.md b/_ru/scala3/book/ca-extension-methods.md new file mode 100644 index 0000000000..672f7d54e3 --- /dev/null +++ b/_ru/scala3/book/ca-extension-methods.md @@ -0,0 +1,145 @@ +--- +layout: multipage-overview +title: Методы расширения +scala3: true +partof: scala3-book +overview-name: "Scala 3 — Book" +type: section +description: В этой главе представлена работа методов расширения в Scala 3. +language: ru +num: 60 +previous-page: ca-contextual-abstractions-intro +next-page: +versionSpecific: true +--- + +В Scala 2 аналогичного результата можно добиться с помощью [неявных классов]({% link _overviews/core/implicit-classes.md %}). + +--- + +Методы расширения позволяют добавлять методы к типу после того, как он был определен, +т.е. они позволяют добавлять новые методы в закрытые классы. +Например, представьте, что кто-то создал класс `Circle`: + +{% tabs ext1 %} +{% tab 'Scala 2 и 3' %} + +```scala +case class Circle(x: Double, y: Double, radius: Double) +``` + +{% endtab %} +{% endtabs %} + +Теперь представим, что необходим метод `circumference`, но нет возможности изменить исходный код `Circle`. +До того как концепция вывода терминов была введена в языки программирования, +единственное, что можно было сделать, это написать метод в отдельном классе или объекте, подобном этому: + +{% tabs ext2 class=tabs-scala-version %} +{% tab 'Scala 2' %} + +```scala +object CircleHelpers { + def circumference(c: Circle): Double = c.radius * math.Pi * 2 +} +``` + +{% endtab %} +{% tab 'Scala 3' %} + +```scala +object CircleHelpers: + def circumference(c: Circle): Double = c.radius * math.Pi * 2 +``` + +{% endtab %} +{% endtabs %} + +Затем этот метод можно было использовать следующим образом: + +{% tabs ext3 %} +{% tab 'Scala 2 и 3' %} + +```scala +val aCircle = Circle(2, 3, 5) + +// без использования метода расширения +CircleHelpers.circumference(aCircle) +``` + +{% endtab %} +{% endtabs %} + +Но методы расширения позволяют создать метод `circumference` для работы с экземплярами `Circle`: + +{% tabs ext4 %} +{% tab 'Только в Scala 3' %} + +```scala +extension (c: Circle) + def circumference: Double = c.radius * math.Pi * 2 +``` + +{% endtab %} +{% endtabs %} + +В этом коде: + +- `Circle` — это тип, к которому будет добавлен метод расширения `circumference` +- Синтаксис `c: Circle` позволяет ссылаться на переменную `c` в методах расширения + +Затем в коде метод `circumference` можно использовать так же, как если бы он был изначально определен в классе `Circle`: + +{% tabs ext5 %} +{% tab 'Только в Scala 3' %} + +```scala +aCircle.circumference +``` + +{% endtab %} +{% endtabs %} + +### Импорт методов расширения + +Представим, что `circumference` определен в пакете `lib` - его можно импортировать с помощью + +{% tabs ext6 %} +{% tab 'Только в Scala 3' %} + +```scala +import lib.circumference + +aCircle.circumference +``` + +{% endtab %} +{% endtabs %} + +Если импорт отсутствует, то компилятор выводит подробное сообщение об ошибке, подсказывая возможный импорт, например так: + +```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 +``` + +## Обсуждение + +Ключевое слово `extension` объявляет о намерении определить один или несколько методов расширения для типа, заключенного в круглые скобки. +Чтобы определить для типа несколько методов расширения, используется следующий синтаксис: + +{% tabs ext7 %} +{% tab 'Только в Scala 3' %} + +```scala +extension (c: Circle) + def circumference: Double = c.radius * math.Pi * 2 + def diameter: Double = c.radius * 2 + def area: Double = math.Pi * c.radius * c.radius +``` + +{% endtab %} +{% endtabs %} diff --git a/_ru/scala3/book/types-others.md b/_ru/scala3/book/types-others.md index a1024a7970..25a0437b1d 100644 --- a/_ru/scala3/book/types-others.md +++ b/_ru/scala3/book/types-others.md @@ -9,7 +9,7 @@ description: В этом разделе упоминаются другие ра language: ru num: 58 previous-page: types-dependent-function -next-page: +next-page: ca-contextual-abstractions-intro --- В Scala есть несколько других расширенных типов, которые не показаны в этой книге, в том числе: From f2b81ff04770d152eb23a0a1f9e7681e98048e53 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: Sat, 15 Jul 2023 08:51:06 +0300 Subject: [PATCH 2/3] Add ca-contextual-abstractions-intro.md in russian --- _includes/version-specific-notice.html | 30 +++++++++++++++++++------- _layouts/multipage-overview.html | 7 +++++- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/_includes/version-specific-notice.html b/_includes/version-specific-notice.html index 1a9ea6832b..4a92f84a6d 100644 --- a/_includes/version-specific-notice.html +++ b/_includes/version-specific-notice.html @@ -2,15 +2,29 @@
{% if include.language == 'scala3' %} - This doc page is specific to Scala 3, - and may cover new concepts not available in Scala 2. Unless - otherwise stated, all the code examples in this page assume - you are using Scala 3. + {% if include.page-language == 'ru' %} + Эта страница документа относится к Scala 3 и + может охватывать новые концепции, недоступные в Scala 2. + Если не указано явно, все примеры кода на этой странице + предполагают, что вы используете Scala 3. + {% else %} + This doc page is specific to Scala 3, + and may cover new concepts not available in Scala 2. Unless + otherwise stated, all the code examples in this page assume + you are using Scala 3. + {% endif %} {% else if include.language == 'scala2' %} - This doc page is specific to features shipped in Scala 2, - which have either been removed in Scala 3 or replaced by an - alternative. Unless otherwise stated, all the code examples - in this page assume you are using Scala 2. + {% if include.page-language == 'ru' %} + Эта страница документа относится к функциям, представленным в Scala 2, + которые либо были удалены в Scala 3, либо заменены альтернативными. + Если не указано явно, все примеры кода на этой странице предполагают, + что вы используете Scala 2. + {% else %} + This doc page is specific to features shipped in Scala 2, + which have either been removed in Scala 3 or replaced by an + alternative. Unless otherwise stated, all the code examples + in this page assume you are using Scala 2. + {% endif %} {% endif %}
diff --git a/_layouts/multipage-overview.html b/_layouts/multipage-overview.html index a9162e4d3d..6ff8b3aa85 100644 --- a/_layouts/multipage-overview.html +++ b/_layouts/multipage-overview.html @@ -18,7 +18,12 @@ {% else if page.scala2 %} {% assign versionSpecificLang = 'scala2' %} {% endif %} - {% include version-specific-notice.html language=versionSpecificLang %} + {% if page.language %} + {% assign pageLanguage = page.language %} + {% else %} + {% assign pageLanguage = 'en' %} + {% endif %} + {% include version-specific-notice.html language=versionSpecificLang page-language=pageLanguage %} {% endif %}