diff --git a/_overviews/scala3-book/scala-for-java-devs.md b/_overviews/scala3-book/scala-for-java-devs.md index 5ed39eb9ee..50d1777677 100644 --- a/_overviews/scala3-book/scala-for-java-devs.md +++ b/_overviews/scala3-book/scala-for-java-devs.md @@ -11,7 +11,7 @@ next-page: scala-for-javascript-devs
-This page provides a comparison between the Java and Scala programming languages by sharing side-by-sde examples of each language. +This page provides a comparison between the Java and Scala programming languages by sharing side-by-side examples of each language. It’s intended for programmers who know Java and want to learn about Scala, specifically by seeing how Scala features compare to Java. @@ -25,13 +25,13 @@ It presents the similarities and differences between Java and Scala at a high le At a high level, Scala shares these similarities with Java: -- Scala code is compiled to *.class* files, packaged in JAR files, and runs on the JVM -- It’s an object-oriented programming (OOP) language +- Scala code is compiled to _.class_ files, packaged in JAR files, and runs on the JVM +- It’s an [object-oriented programming][modeling-oop] (OOP) language - It’s statically typed -- Both languages have support for immutable collections, lambdas, and higher-order functions +- Both languages have support for lambdas and [higher-order functions][hofs] - They can both be used with IDEs like IntelliJ IDEA and Microsoft VS Code - Projects can be built with build tools like Gradle, Ant, and Maven -- It has terrific libraries and frameworks for building server-side, network-intensive applications, including web server applications, microservices, machine learning, and more +- It has terrific libraries and frameworks for building server-side, network-intensive applications, including web server applications, microservices, machine learning, and more (see the [“Awesome Scala” list](https://github.com/lauris/awesome-scala)) - Both Java and Scala can use Scala libraries: - They can use the [Akka actors library](https://akka.io) to build actor-based concurrent systems, and Apache Spark to build data-intensive applications - They can use the [Play Framework](https://www.playframework.com) to develop server-side applications @@ -42,13 +42,14 @@ At a high level, Scala shares these similarities with Java: Also at a high level, the differences between Java and Scala are: -- Scala has a concise but readable syntax; we call it *expressive* +- Scala has a concise but readable syntax; we call it _expressive_ - Though it’s statically typed, Scala often feels like a dynamic language - Scala is a pure OOP language, so every object is an instance of a class, and symbols like `+` and `+=` that look like operators are really methods; this means that you can create your own operators - In addition to being a pure OOP language, Scala is also a pure FP language; in fact, it encourages a fusion of OOP and FP, with functions for the logic and objects for modularity -- Everything in Scala is an *expression*: constructs like `if` statements, `for` loops, `match` expressions, and even `try`/`catch` expressions all have return values +- 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 -- The Scala ecosystem has other build tools in sbt, Mill, and others +- 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 @@ -66,22 +67,22 @@ Finally, these are some of the differences you’ll see every day when writing c - Scala’s syntax is extremely consistent - Variables and parameters are defined as `val` (immutable, like `final` in Java) or `var` (mutable) -- *Type inference* makes your code feel dynamically typed, and helps to keep your code brief +- _Type inference_ makes your code feel dynamically typed, and helps to keep your code brief - In addition to simple `for` loops, Scala has powerful `for` comprehensions that yield results based on your algorithms - Pattern matching and `match` expressions will change the way you write code -- Writing immutable code by default leads to writing *expressions* rather than *statements*; in time you see that writing expressions simplifies your code (and your tests) -- *Toplevel definitions* let you put method, field, and other definitions anywhere, also leading to concise, expressive code -- You can create *mixins* by “mixing” multiple traits into classes and objects (traits are similar to interfaces in Java 8 and newer) -- Classes are closed by default, supporting Joshua Bloch’s *Effective Java* idiom, “Design and document for inheritance or else forbid it” -- Scala’s *contextual abstractions* and *term inference* provide a collection of features: - - *Extension methods* let you add new functionality to closed classes - - *Given* instances let you define terms that the compiler can synthesize at *using* points, making your code less verbose and essentially letting the compiler write code for you - - *Multiversal equality* lets you limit equality comparisons---at compile time---to only those comparisons that make sense +- Writing immutable code by default leads to writing _expressions_ rather than _statements_; in time you see that writing expressions simplifies your code (and your tests) +- [Toplevel definitions][toplevel] let you put method, field, and other definitions anywhere, also leading to concise, expressive code +- You can create _mixins_ by “mixing” multiple traits into classes and objects (traits are similar to interfaces in Java 8 and newer) +- Classes are closed by default, supporting Joshua Bloch’s _Effective Java_ idiom, “Design and document for inheritance or else forbid it” +- Scala’s [contextual abstractions][contextual] and _term inference_ provide a collection of features: + - [Extension methods][extension-methods] let you add new functionality to closed classes + - [_Given_ instances][givens] let you define terms that the compiler can synthesize at _using_ points, making your code less verbose and essentially letting the compiler write code for you + - [Multiversal equality][multiversal] lets you limit equality comparisons---at compile time---to only those comparisons that make sense - Scala has state of the art, third-party, open source functional programming libraries - Scala case classes are like records in Java 14; they help you model data when writing FP code, with built-in support for concepts like pattern matching and cloning -- Thanks to features like by-name parameters, infix notation, optional parentheses, extension methods, and higher-order functions, you can create your own “control structures” and DSLs +- Thanks to features like by-name parameters, infix notation, optional parentheses, extension methods, and [higher-order functions][hofs], you can create your own “control structures” and DSLs - Scala files do not have to be named according to the classes or traits they contain -- Many other goodies: companion classes and objects, macros, union and intersection types, toplevel definitions, numeric literals, multiple parameter lists, default values for parameters, named arguments, and more +- Many other goodies: companion classes and objects, macros, [union][union-types] and [intersection][intersection-types], numeric literals, multiple parameter lists, default values for parameters, named arguments, and more ### Features compared with examples @@ -520,7 +521,7 @@ These interfaces and traits have concrete, implemented methods (default methods) ## Control structures -This section compares control structures in Java and Scala. +This section compares [control structures][control] in Java and Scala. ### `if` statement, one line: @@ -889,7 +890,7 @@ Called a _ternary operator_ in Java: ## Collections classes -This section compares the collections classes that are available in Java and Scala. +This section compares the [collections classes][collections-classes] that are available in Java and Scala. ### Immutable collections classes @@ -962,8 +963,34 @@ Examples of how to create instances of immutable collections. ### Mutable collections classes -Scala has mutable collections classes like `ArrayBuffer`, `Map`, and `Set`, in its *scala.collection.mutable* package. -After importing them into the current scope, they’re created just like the immutable `List`, `Vector`, `Map`, and `Set` examples just shown. +Scala has mutable collections classes like `ArrayBuffer`, `Map`, and `Set` in its _scala.collection.mutable_ package. +After [importing them][imports] into the current scope, they’re created just like the immutable `List`, `Vector`, `Map`, and `Set` examples just shown. + +Scala also has an `Array` class, which you can think of as being a wrapper around the Java `array` primitive type. +A Scala `Array[A]` maps to a Java `A[]`, so you can think of this Scala `Array[String]`: + +```scala +val a = Array("a", "b") +``` + +as being backed by this Java `String[]`: + +```scala +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`: + +```scala +val nums = Array(1, 2, 3, 4, 5) +val doubledNums = nums.map(_ * 2) +val filteredNums = nums.filter(_ > 2) +``` + +Because the Scala `Array` is represented in the same way as the Java `array`, you can easily use Java methods that return arrays in your Scala code. + +> Despite that discussion of `Array`, bear in mind that often in Scala there are alternatives to `Array` that might be better suited. +> Arrays are useful for interoperating with other languages (Java, JavaScript) and they may also be useful when writing low-level code that needs to squeeze maximum performance out of the underlying platform. But in general, when you need to use a sequence, the Scala idiom is to prefer immutable sequences like `Vector` and `List`, and then use `ArrayBuffer` if and when when you really need a mutable sequence. You can also convert between Java and Scala collections classes with the Scala `CollectionConverters` objects. There are two objects in different packages, one for converting from Java to Scala, and another for converting from Scala to Java. @@ -1014,13 +1041,13 @@ With the ability to treat Java collections as streams, Java and Scala now have m - `findFirst`/`find` - `reduce` -If you’re used to using these methods with lambda expressions in Java, you’ll find it easy to use the same methods on Scala’s collection classes. +If you’re used to using these methods with lambda expressions in Java, you’ll find it easy to use the same methods on Scala’s [collection classes][collections-classes]. -Scala also has *dozens* of other collections methods, including `head`, `tail`, `drop`, `take`, `distinct`, `flatten`, and many more. -At first you may wonder why there are so many methods, but after working with Scala you’ll realize that because of these methods, you rarely ever need to write custom `for` loops any more. +Scala also has _dozens_ of other [collections methods][collections-methods], including `head`, `tail`, `drop`, `take`, `distinct`, `flatten`, and many more. +At first you may wonder why there are so many methods, but after working with Scala you’ll realize that _because_ of these methods, you rarely ever need to write custom `for` loops any more. -(This also means that you rarely need to *read* custom `for` loops, as well. -Because developers tend to spend on the order of ten times as much time *reading* code as *writing* code, this is significant.) +(This also means that you rarely need to _read_ custom `for` loops, as well. +Because developers tend to spend on the order of ten times as much time _reading_ code as _writing_ code, this is significant.) @@ -1195,10 +1222,10 @@ throws NumberFormatException { ### Scala doesn’t use checked exceptions -The Scala idiom is to *not* use checked exceptions like this. +The Scala idiom is to _not_ use checked exceptions like this. When working with code that can throw exceptions, you can use `try`/`catch`/`finally` blocks to catch exceptions from code that throws them, but how you proceed from there is different. -The best way to explain this is that Scala code consists of *expressions*, which return values. +The best way to explain this is that Scala code consists of _expressions_, which return values. As a result, you end up writing your code as a series of algebraic expressions: ```scala @@ -1251,13 +1278,12 @@ 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. This includes: -- Everything related to Scala’s contextual abstractions +- Everything related to Scala’s [contextual abstractions][contextual] - Several Scala method features: - Multiple parameter lists - Default parameter values - Using named arguments when calling methods -- Case classes (like “records” in Java 14) and case objects -- Companion classes and objects +- Case classes (like “records” in Java 14), case objects, and companion classes and objects (see the [Domain Modeling][modeling-intro]) chapter - The ability to create your own control structures and DSLs - [Toplevel definitions][toplevel] - Pattern matching @@ -1271,11 +1297,33 @@ This includes: - Macros and metaprogramming -[toplevel]: {% link _overviews/scala3-book/taste-toplevel-definitions.md %} -[opaque]: {% link _overviews/scala3-book/types-opaque-types.md %} +[collections-classes]: {% link _overviews/scala3-book/collections-classes.md %} +[collections-methods]: {% link _overviews/scala3-book/collections-methods.md %} +[control]: {% link _overviews/scala3-book/control-structures.md %} [equality]: {% link _overviews/scala3-book/ca-multiversal-equality.md %} -[type-classes]: {% link _overviews/scala3-book/ca-type-classes.md %} [error-handling]: {% link _overviews/scala3-book/fp-functional-error-handling.md %} +[extension-methods]: {% link _overviews/scala3-book/ca-extension-methods.md %} +[givens]: {% link _overviews/scala3-book/ca-given-using-clauses.md %} +[hofs]: {% link _overviews/scala3-book/fun-hofs.md %} +[imports]: {% link _overviews/scala3-book/packaging-imports.md %} +[modeling-intro]: {% link _overviews/scala3-book/domain-modeling-intro.md %} +[modeling-oop]: {% link _overviews/scala3-book/domain-modeling-oop.md %} +[opaque]: {% link _overviews/scala3-book/types-opaque-types.md %} +[tools]: {% link _overviews/scala3-book/scala-tools.md %} +[toplevel]: {% link _overviews/scala3-book/taste-toplevel-definitions.md %} +[type-classes]: {% link _overviews/scala3-book/ca-type-classes.md %} + + -
+ +[concurrency]: {% link _overviews/scala3-book/concurrency.md %} +[contextual]: {% link _overviews/scala3-book/ca-contextual-abstractions-intro.md %} +[control]: {% link _overviews/scala3-book/control-structures.md %} +[fp-intro]: {% link _overviews/scala3-book/fp-intro.md %} +[intersection-types]: {% link _overviews/scala3-book/types-intersection.md %} +[modeling-fp]: {% link _overviews/scala3-book/domain-modeling-fp.md %} +[multiversal]: {% link _overviews/scala3-book/ca-multiversal-equality.md %} +[union-types]: {% link _overviews/scala3-book/types-union.md %} + + diff --git a/_overviews/scala3-book/scala-for-javascript-devs.md b/_overviews/scala3-book/scala-for-javascript-devs.md index 6d71d68a4c..0237e0d63c 100644 --- a/_overviews/scala3-book/scala-for-javascript-devs.md +++ b/_overviews/scala3-book/scala-for-javascript-devs.md @@ -29,14 +29,14 @@ At a high level, Scala shares these similarities with JavaScript: - Both have a relatively simple, concise syntax - Both support a C/C++/Java style curly-brace syntax for writing methods and other block of code - Both include features (like classes) for object-oriented programming (OOP) -- Both include features (like lambdas) for functional programming (FP) +- Both include features (like lambdas) for [functional programming][fp-intro] (FP) - JavaScript runs in the browser and other environments like Node.js. The [Scala.js](https://www.scala-js.org) flavor of Scala targets JavaScript and Scala programs can thus run in the same environments. - Developers write server-side applications in JavaScript and Scala using [Node.js](https://nodejs.org); projects like the [Play Framework](https://www.playframework.com/) also let you write server-side applications in Scala - 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 uses futures and promises) +- Both JavaScript and Scala support _promises_ as a way of running asynchronous computations ([Scala concurrency][concurrency] uses futures and promises) ### High-level differences @@ -45,11 +45,11 @@ Also at a high level, some of the differences between JavaScript and Scala are: - JavaScript is dynamically typed, and Scala is statically typed - Although Scala is statically typed, features like type inference make it feel like a dynamic language (as you’ll see in the examples that follow) - Scala idioms favor immutability by default: you’re encouraged to use immutable variables and immutable collections -- Scala has a concise but readable syntax; we call it *expressive* +- Scala has a concise but readable syntax; we call it _expressive_ - Scala is a pure OOP language, so every object is an instance of a class, and symbols like `+` and `+=` that look like operators are really methods; this means that you can create your own methods that work as operators - 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 +- 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 ### Programming level differences @@ -59,15 +59,15 @@ At a lower level, these are some of the differences you’ll see every day when - Scala variables and parameters are defined with `val` (immutable, like a JavaScript `const`) or `var` (mutable, like a JavaScript `var` or `let`) - Scala does not use semi-colons at the end of lines - Scala is statically-typed, though in many situations you don’t need to declare the type -- Scala uses traits as interfaces and to create *mixins* +- Scala uses traits as interfaces and to create _mixins_ - In addition to simple `for` loops, Scala has powerful `for` comprehensions that yield results based on your algorithms - Pattern matching and `match` expressions will change the way you write code -- Scala’s *contextual abstractions* and *term inference* provide a collection of features: - - *Extension methods* let you add new functionality to closed classes without breaking modularity, by being available only in specific scopes (as opposed to monkey-patching, which can pollute other areas of the code) - - *Given* instances let you define terms that the compiler can use to synthesize code for you - - Type safety and *multiversal equality* let you limit equality comparisons---at compile time---to only those comparisons that make sense -- Thanks to features like by-name parameters, infix notation, optional parentheses, extension methods, and higher-order functions, you can create your own “control structures” and DSLs -- Many other goodies that you can read about throughout this book: case classes, companion classes and objects, macros, union and intersection types, multiple parameter lists, named arguments, and more... +- Scala’s [contextual abstractions][contextual] and _term inference_ provide a collection of features: + - [Extension methods][extension-methods] let you add new functionality to closed classes without breaking modularity, by being available only in specific scopes (as opposed to monkey-patching, which can pollute other areas of the code) + - [Given instances][givens] let you define terms that the compiler can use to synthesize code for you + - Type safety and [multiversal equality][multiversal] let you limit equality comparisons---at compile time---to only those comparisons that make sense +- Thanks to features like by-name parameters, infix notation, optional parentheses, extension methods, and [higher-order functions][hofs], you can create your own “control structures” and DSLs +- Many other goodies that you can read about throughout this book: case classes, companion classes and objects, macros, [union][union-types] and [intersection][intersection-types] types, multiple parameter lists, named arguments, and more @@ -137,7 +137,7 @@ The rule of thumb in Scala is to declare variables using `val`, unless there’s ## Naming standards -JavaScript and Scala generally use the same *CamelCase* naming standards. +JavaScript and Scala generally use the same _CamelCase_ naming standards. Variables are named like `myVariableName`, methods are named like `lastIndexOf`, and classes and object are named like `Animal` and `PrintedBook`. @@ -300,7 +300,7 @@ The biggest difference is that Scala doesn’t offer `++` and `--` operators. -Perhaps the biggest difference is that “operators” like `+` and `-` are really *methods* in Scala, not operators. +Perhaps the biggest difference is that “operators” like `+` and `-` are really _methods_ in Scala, not operators. Scala numbers also have these related methods: ```scala @@ -419,7 +419,7 @@ Dates are another commonly used type in both languages. In this case, Scala uses the date and time classes that come with Java. Many date/time methods are similar between JavaScript and Scala. -See [the *java.time* package](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html) for more details. +See [the _java.time_ package](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html) for more details. @@ -522,7 +522,7 @@ Both JavaScript and Scala let you define anonymous functions, which you can pass In Scala you rarely define a function using the first syntax shown. Instead, you often define anonymous functions right at the point of use. -Many collections methods are higher-order functions and accept function parameters, so you write code like this: +Many collections methods are [higher-order functions][hofs] and accept function parameters, so you write code like this: ```scala // map method, long form @@ -543,7 +543,7 @@ List(1,2,3,4,5).filter(_ < 3).map(_ * 10) // List(10, 20) ## Classes Scala has both classes and case classes. -A *class* is similar to a JavaScript class, and is generally intended for use in OOP style applications (though they can also be used in FP code), and *case classes* have additional features that make them very useful in FP style applications. +A _class_ is similar to a JavaScript class, and is generally intended for use in [OOP style applications][modeling-oop] (though they can also be used in FP code), and _case classes_ have additional features that make them very useful in [FP style applications][modeling-fp]. The following example shows how to create several types as enumerations, and then defines an OOP-style `Pizza` class. At the end, a `Pizza` instance is created and used: @@ -1069,7 +1069,7 @@ A `for` comprehension is a `for` loop that uses `yield` to return (yield) a valu ## switch & match Where JavaScript has `switch` statements, Scala has `match` expressions. -Like everything else in Scala, these truly are *expressions*, meaning they return a result: +Like everything else in Scala, these truly are _expressions_, meaning they return a result: ```scala val day = 1 @@ -1108,14 +1108,14 @@ def isPerson(x: Matchable): Boolean = x match ## Collections classes -Scala has different collections classes for different needs. +Scala has different [collections classes][collections-classes] for different needs. -Common *immutable* sequences are: +Common _immutable_ sequences are: - `List` - `Vector` -Common *mutable* sequences are: +Common _mutable_ sequences are: - `Array` - `ArrayBuffer` @@ -1208,7 +1208,7 @@ val men = List("Fred", "Barney") // List(Fred, Barney) val couples = women.zip(men) // List((Wilma,Fred), (Betty,Barney)) ``` -Scala has *many* more methods that are available to you. +Scala has _many_ more methods that are available to you. The benefits of all these methods are: - You don’t have to write custom `for` loops to solve problems @@ -1351,7 +1351,7 @@ There are other concepts in Scala which currently have no equivalent in JavaScri - Using traits as interfaces - Case classes - Companion classes and objects -- The ability to create your own control structures and DSLs +- The ability to create your own [control structures][control] and DSLs - Advanced features of `match` expressions and pattern matching - `for` comprehensions - Infix methods @@ -1359,7 +1359,19 @@ There are other concepts in Scala which currently have no equivalent in JavaScri - More ... +[collections-classes]: {% link _overviews/scala3-book/collections-classes.md %} +[concurrency]: {% link _overviews/scala3-book/concurrency.md %} [contextual]: {% link _overviews/scala3-book/ca-contextual-abstractions-intro.md %} +[control]: {% link _overviews/scala3-book/control-structures.md %} +[extension-methods]: {% link _overviews/scala3-book/ca-extension-methods.md %} +[fp-intro]: {% link _overviews/scala3-book/fp-intro.md %} +[givens]: {% link _overviews/scala3-book/ca-given-using-clauses.md %} +[hofs]: {% link _overviews/scala3-book/fun-hofs.md %} +[intersection-types]: {% link _overviews/scala3-book/types-intersection.md %} +[modeling-fp]: {% link _overviews/scala3-book/domain-modeling-fp.md %} +[modeling-oop]: {% link _overviews/scala3-book/domain-modeling-oop.md %} +[multiversal]: {% link _overviews/scala3-book/ca-multiversal-equality.md %} +[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 112d0ca98f..958fa50033 100644 --- a/_overviews/scala3-book/scala-for-python-devs.md +++ b/_overviews/scala3-book/scala-for-python-devs.md @@ -37,26 +37,26 @@ The two languages are first compared at a high level, and then at an everyday pr At a high level, Scala shares these *similarities* with Python: - Both are high-level programming languages, where you don’t have to concern yourself with low-level concepts like pointers and manual memory management -- Both have a relatively simple, concise syntax -- Both are functional programming (FP) languages +- Both have a relatively simple, concise syntax +- Both support a [functional style of programming][fp-intro] - Both are object-oriented programming (OOP) languages - Both have comprehensions: Python has list comprehensions and Scala has `for` comprehensions -- Both languages have support for lambdas and higher-order functions +- Both languages have support for lambdas and [higher-order functions][hofs] - Both can be used with [Apache Spark](https://spark.apache.org) for big data processing - Both have a wealth of terrific libraries ### High level differences -Also at a high level, the *differences* between Python and Scala are: +Also at a high level, the _differences_ between Python and Scala are: - Python is dynamically typed, and Scala is statically typed - 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) +- 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 -- Everything in Scala is an *expression*: constructs like `if` statements, `for` loops, `match` expressions, and even `try`/`catch` expressions all have return values +- 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 +- Scala has excellent support for [concurrent and parallel programming][concurrency] ### Programming level similarities @@ -68,19 +68,19 @@ This section looks at the similarities you’ll see between Python and Scala whe - The syntax for defining methods is similar - Both have lists, dictionaries (maps), sets, and tuples - Both have comprehensions for mapping and filtering -- Both have higher-order functions and strong support for lambdas -- With Scala 3’s toplevel definitions you can put method, field, and other definitions anywhere - - One difference is that Python can operate without even declaring a single method, while Scala 3 can’t do _everything_ at the toplevel; for instance, a `@main def` method is required to start a Scala application +- With Scala 3’s [toplevel definitions][toplevel] you can put method, field, and other definitions anywhere + - One difference is that Python can operate without even declaring a single method, while Scala 3 can’t do _everything_ at the toplevel; for instance, a [main method][main-method] (`@main def`) is required to start a Scala application ### Programming level differences Also at a programming level, these are some of the differences you’ll see every day when writing code: -- Scala’s syntax is extremely consistent: - - Lists, maps, sets, and tuples are all created and accessed similarly - - Collections classes generally have most of the same higher-order functions +- Programming in Scala feels very consistent: - `val` and `var` fields are used consistently to define fields and parameters + - Lists, maps, sets, and tuples are all created and accessed similarly; for instance, parentheses are used to create all types---`List(1,2,3)`, `Set(1,2,3)`, `Map(1->"one")`---just like creating any other Scala class + - [Collections classes][collections-classes] generally have most of the same higher-order functions - Pattern matching is used consistently throughout the language + - The syntax that’s used to define functions that are passed into methods is the same syntax that’s used to define anonymous functions - Scala variables and parameters are defined with the `val` (immutable) or `var` (mutable) keywords - Scala idioms prefer immutable data structures - Scala has terrific IDE support with IntelliJ IDEA and Microsoft VS Code @@ -89,22 +89,23 @@ Also at a programming level, these are some of the differences you’ll see ever - Scala is statically typed, so you declare types for method parameters, method return values, and in other places - Pattern matching and `match` expressions are used extensively in Scala (and will change the way you write code) - Traits are used heavily in Scala; interfaces and abstract classes are used less often in Python -- Scala’s *contextual abstractions* and *term inference* provide a collection of different features: - - *Extension methods* let you easily add new functionality to classes using a clear syntax - - *Multiversal equality* lets you limit equality comparisons---at compile time---to only those comparisons that make sense -- Scala has state-of-the-art open source functional programming libraries +- Scala’s [contextual abstractions][contextual] and _term inference_ provide a collection of different features: + - [Extension methods][extension-methods] let you easily add new functionality to classes using a clear syntax + - [Multiversal equality][multiversal] lets you limit equality comparisons---at compile time---to only those comparisons that make sense +- Scala has state-of-the-art open source functional programming libraries (see the [“Awesome Scala” list](https://github.com/lauris/awesome-scala)) - You can create your own “control structures” and DSLs, thanks to features like objects, by-name parameters, infix notation, optional parentheses, extension methods, higher-order functions, and more -- Scala code can run in the JVM and even be compiled to native images (using Scala Native and GraalVM) for high performance -- Many other goodies: case classes, companion classes and objects, macros, union and intersection types, toplevel definitions, numeric literals, multiple parameter lists, and more - +- Scala code can run in the JVM and even be compiled to native images (using [Scala Native](https://github.com/scala-native/scala-native) and [GraalVM](https://www.graalvm.org)) for high performance +- Many other goodies: case classes, companion classes and objects, macros, [union][union-types] and [intersection][intersection-types] types, [toplevel definitions][toplevel], numeric literals, multiple parameter lists, and more ### Features compared with examples Given that introduction, the following sections provide side-by-side comparisons of Python and Scala programming language features. -> The general Python standard is to indent code with four spaces, but in the following examples only two spaces are used. -> This is only done so the examples can be shown side by side. +{% comment %} +TODO: Update the Python examples to use four spaces. I started to do this, but then thought it would be better to do that in a separate PR. +{% endcomment %} + ## Comments @@ -336,7 +337,7 @@ This section provides comparisons of features related to OOP-style classes and m If you’re familiar with Java 8 and newer, Scala traits are similar to those Java interfaces. Traits are used all the time in Scala, while Python interfaces and abstract classes are used much less often. -Therefore, rather than attempt to compare the two side by side, this example shows how to use Scala traits to build a small solution to a simulated math problem: +Therefore, rather than attempt to compare the two, this example shows how to use Scala traits to build a small solution to a simulated math problem: ```scala trait Adder: @@ -352,13 +353,13 @@ sm.add(1,1) // 2 sm.multiply(2,2) // 4 ``` -There are many other ways to use traits with classes and objects, but this gives you a little idea of how they can be used to organize concepts into logical groups of behavior, and then merge them as needed to create a complete solution. +There are [many other ways to use traits with classes and objects][modeling-intro], but this gives you a little idea of how they can be used to organize concepts into logical groups of behavior, and then merge them as needed to create a complete solution. ## Control structures -This section compares control structures in Python and Scala. +This section compares [control structures][control-structures] in Python and Scala. Both languages have constructs like `if`/`else`, `while`, `for` loops, and `try`. Scala also has `match` expressions. @@ -727,13 +728,13 @@ Scala also has `match` expressions. -Match expressions and pattern matching are a big part of the Scala programming experience, but only a few `match` expression features are shown here. See the [Control Structures][control_structures] page for many more examples. +Match expressions and pattern matching are a big part of the Scala programming experience, but only a few `match` expression features are shown here. See the [Control Structures][control-structures] page for many more examples. ## Collections classes -This section compares the collections classes that are available in Python and Scala, including lists, dictionaries/maps, sets, and tuples. +This section compares the [collections classes][collections-classes] that are available in Python and Scala, including lists, dictionaries/maps, sets, and tuples. ### Lists @@ -1297,7 +1298,7 @@ This section compares enums (enumerations) in Python and Scala 3. There are other concepts in Scala which currently don’t have equivalent functionality in Python. Follow the links below for more details: -- Most concepts related to [contextual abstractions][contextual], such as [extension methods][extension], [type classes][type_classes], implicit values +- Most concepts related to [contextual abstractions][contextual], such as [extension methods][extension-methods], [type classes][type-classes], implicit values - Scala allows multiple parameter lists, which enables features like partially-applied functions, and the ability to create your own DSLs - Case classes, which are extremely useful for functional programming and pattern matching - The ability to create your own control structures and DSLs @@ -1307,12 +1308,21 @@ Follow the links below for more details: - Macros and metaprogramming -[toplevel]: {% link _overviews/scala3-book/taste-toplevel-definitions.md %} +[collections-classes]: {% link _overviews/scala3-book/collections-classes.md %} +[concurrency]: {% link _overviews/scala3-book/concurrency.md %} [contextual]: {% link _overviews/scala3-book/ca-contextual-abstractions-intro.md %} -[extension]: {% link _overviews/scala3-book/ca-extension-methods.md %} -[type_classes]: {% link _overviews/scala3-book/types-type-classes.md %} +[control-structures]: {% link _overviews/scala3-book/control-structures.md %} +[extension-methods]: {% link _overviews/scala3-book/ca-extension-methods.md %} +[fp-intro]: {% link _overviews/scala3-book/fp-intro.md %} +[hofs]: {% link _overviews/scala3-book/fun-hofs.md %} +[intersection-types]: {% link _overviews/scala3-book/types-intersection.md %} +[main-method]: {% link _overviews/scala3-book/methods-main-methods.md %} +[modeling-intro]: {% link _overviews/scala3-book/domain-modeling-intro.md %} [multiversal]: {% link _overviews/scala3-book/ca-multiversal-equality.md %} -[control_structures]: {% link _overviews/scala3-book/control-structures.md %} +[toplevel]: {% link _overviews/scala3-book/taste-toplevel-definitions.md %} +[type-classes]: {% link _overviews/scala3-book/types-type-classes.md %} +[union-types]: {% link _overviews/scala3-book/types-union.md %} + diff --git a/_overviews/scala3-book/scala-tools.md b/_overviews/scala3-book/scala-tools.md index fa5ff66760..81f7177515 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, 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. > To install sbt, see [its download page](https://www.scala-sbt.org/download.html) or our [Getting Started][getting_started] page. @@ -38,13 +38,13 @@ $ mkdir hello $ cd hello ``` -Then create a file named *build.sbt* that contains this line: +Then create a file named _build.sbt_ 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: +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") @@ -70,12 +70,12 @@ 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*. +When you look at your directory, you’ll see that sbt has created two directories named _project_ and _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 }}")` +> 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 @@ -107,9 +107,9 @@ src/ target/ ``` -You can also add a *lib* directory under the root directory if you want to add unmanaged dependencies---JAR files---to your project. +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: +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/ @@ -123,7 +123,7 @@ src/ ### “Hello, world” with an sbt directory structure {% comment %} -TODO: using something like `sbt new scala/scala3.g8` may eventually +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; @@ -165,10 +165,10 @@ If you see that, you’re in great shape for the next step. At this point you only need two more things to run a “Hello, world” project: -- A *build.sbt* file -- A *Hello.scala* file +- 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: +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" @@ -183,8 +183,8 @@ 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: +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") @@ -278,7 +278,7 @@ See Coursier’s [launch page](https://get-coursier.io/docs/cli-launch) for more ### 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: +As with the previous lesson, create an sbt project directory structure for a project named _HelloScalaTest_ with the following commands: ```bash $ mkdir HelloScalaTest @@ -290,7 +290,7 @@ $ mkdir project target ### Creating the build.sbt file -Next, create a *build.sbt* file in the root directory of your project with these contents: +Next, create a _build.sbt_ file in the root directory of your project with these contents: ```scala name := "HelloScalaTest" @@ -311,14 +311,14 @@ The `libraryDependencies` lines tell sbt to include the dependencies (JAR files) ### 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*: +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: +Then, inside that directory, create a file named _MathUtils.scala_ with these contents: ```scala package math @@ -352,14 +352,14 @@ With that compiled, let’s create a ScalaTest file to test the `double` method. 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: +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: +Next, create a file named _MathUtilsTests.scala_ in that directory with the following contents: ```scala package math @@ -419,7 +419,7 @@ 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. +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. diff --git a/_overviews/scala3-book/taste-modeling.md b/_overviews/scala3-book/taste-modeling.md index 0a6b4f9ed3..aaee4fa19a 100644 --- a/_overviews/scala3-book/taste-modeling.md +++ b/_overviews/scala3-book/taste-modeling.md @@ -35,10 +35,6 @@ Scala traits can be used as simple interfaces, but they can also contain abstrac They provide a great way for you to organize behaviors into small, modular units. Later, when you want to create concrete implementations of attributes and behaviors, classes and objects can extend traits, mixing in as many traits as needed to achieve the desired behavior. -{% comment %} -TODO: Need a better example. This one shows behaviors, not data. -{% endcomment %} - As an example of how to use traits as interfaces, here are three traits that define well-organized and modular behaviors for animals like dogs and cats: ```scala