Skip to content

Scala 3 uses * as wildcard in imports #1956

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions _overviews/scala3-book/ca-given-imports.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,23 @@ object A:
def f(using TC) = ???

object B:
import A._ // import all non-given members
import A.* // import all non-given members
import A.given // import the given instance
```

In this code the `import A._` clause of object `B` imports all members of `A` *except* the `given` instance, `tc`.
In this code the `import A.*` clause of object `B` imports all members of `A` *except* the `given` instance, `tc`.
Conversely, the second import, `import A.given`, imports *only* that `given` instance.
The two `import` clauses can also be merged into one:

```scala
object B:
import A.{given, _}
import A.{given, *}
```


## Discussion

The wildcard selector `_` brings all definitions other than givens or extensions into scope, whereas a `given` selector brings all *givens*---including those resulting from extensions---into scope.
The wildcard selector `*` brings all definitions other than givens or extensions into scope, whereas a `given` selector brings all *givens*---including those resulting from extensions---into scope.

These rules have two main benefits:

Expand Down
6 changes: 3 additions & 3 deletions _overviews/scala3-book/domain-modeling-fp.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ A pizza can be thought of as a _compound_ container of the different attributes
We can use a `case` class to describe that a `Pizza` consists of a `crustSize`, `crustType`, and potentially multiple `Topping`s:

```scala
import CrustSize._
import CrustType._
import Topping._
import CrustSize.*
import CrustType.*
import Topping.*

case class Pizza(
crustSize: CrustSize,
Expand Down
2 changes: 1 addition & 1 deletion _overviews/scala3-book/domain-modeling-oop.md
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ It is important to point out that the implementation of `notify` can only safely
### Using the Component
Finally, the following code illustrates how to use our `SensorReader` component:
```scala
import SensorReader._
import SensorReader.*

// setting up a network
val s1 = Sensor("sensor1")
Expand Down
4 changes: 2 additions & 2 deletions _overviews/scala3-book/interacting-with-java.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ You can convert that Java list to a Scala `Seq`, using the conversion utilities

```scala
// scala
import scala.jdk.CollectionConverters._
import scala.jdk.CollectionConverters.*
import java.util.List

def testList =
Expand Down Expand Up @@ -103,7 +103,7 @@ But by using the _scala.jdk.OptionConverters_ methods, you can convert them to S

```scala
import java.util.Optional
import scala.jdk.OptionConverters._
import scala.jdk.OptionConverters.*

val optionalString = JavaClass.oString // Optional[foo]
val optionString = optionalString.toScala // Some(foo)
Expand Down
2 changes: 1 addition & 1 deletion _overviews/scala3-book/methods-main-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ For instance, the `happyBirthday` method above generates additional code equival

```scala
final class happyBirthday {
import scala.util.{CommandLineParser => CLP}
import scala.util.{CommandLineParser as CLP}
<static> def main(args: Array[String]): Unit =
try
happyBirthday(
Expand Down
38 changes: 18 additions & 20 deletions _overviews/scala3-book/packaging-imports.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,10 @@ They’re explained more in the subsections that follow.
Import statements are also used to import `given` instances into scope.
Those are discussed at the end of this chapter.

Two notes before moving on:
A note before moving on:

> Import clauses are not required for accessing members of the same package.

- Import clauses are not required for accessing members of the same package.
- When the `_` character is used in Scala import statements, it’s similar to the `*` character in Java.
One reason for this difference is that in Scala, the `*` character can be used for method names.


### Importing one or more members
Expand Down Expand Up @@ -113,7 +112,7 @@ import java.io.{File, IOException, FileNotFoundException}
When you want to import everything from the *java.io* package, use this syntax:

```scala
import java.io._
import java.io.*
```


Expand All @@ -123,15 +122,15 @@ Sometimes it can help to rename entities when you import them to avoid name coll
For instance, if you want to use the Scala `List` class and also the *java.util.List* class at the same time, you can rename the *java.util.List* class when you import it:

```scala
import java.util.{List => JavaList}
import java.util.{List as JavaList}
```

Now you use the name `JavaList` to refer to that class, and use `List` to refer to the Scala list class.

You can also rename multiple members at one time using this syntax:

```scala
import java.util.{Date => JDate, HashMap => JHashMap, _}
import java.util.{Date as JDate, HashMap as JHashMap, *}
```

That line of code says, “Rename the `Date` and `HashMap` classes as shown, and import everything else in the _java.util_ package without renaming any other members.”
Expand All @@ -143,7 +142,7 @@ You can also *hide* members during the import process.
This `import` statement hides the *java.util.Random* class, while importing everything else in the *java.util* package:

```scala
import java.util.{Random => _, _}
import java.util.{Random as _, *}
```

If you try to access the `Random` class it won’t work, but you can access all other members from that package:
Expand All @@ -158,8 +157,7 @@ new ArrayList // works
To hide multiple members during the import process, list them before using the final wildcard import:

```scala
scala> import java.util.{List => _, Map => _, Set => _, _}
import java.util.{List=>_, Map=>_, Set=>_, _}
scala> import java.util.{List as _, Map as _, Set as _, *}
```

Once again those classes are hidden, but you can use all other classes in *java.util*:
Expand Down Expand Up @@ -223,13 +221,13 @@ When you want to import members in a way similar to the Java “static import”
Use this syntax to import all static members of the Java `Math` class:

```scala
import java.lang.Math._
import java.lang.Math.*
```

Now you can access static `Math` class methods like `sin` and `cos` without having to precede them with the class name:

```scala
import java.lang.Math._
import java.lang.Math.*

val a = sin(0) // 0.0
val b = cos(PI) // -1.0
Expand All @@ -240,8 +238,8 @@ val b = cos(PI) // -1.0

Two packages are implicitly imported into the scope of all of your source code files:

- java.lang._
- scala._
- java.lang.*
- scala.*

The Scala `Predef` object is also imported by default.

Expand All @@ -256,7 +254,7 @@ In the rare event there’s a naming conflict and you need to import something f
```
package accounts

import _root_.users._
import _root_.accounts.*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch!

```


Expand All @@ -273,22 +271,22 @@ object A:
def f(using TC) = ???

object B:
import A._ // import all non-given members
import A.* // import all non-given members
import A.given // import the given instance
```

In this code, the `import A._` clause of object `B` imports all members of `A` *except* the `given` instance `tc`.
In this code, the `import A.*` clause of object `B` imports all members of `A` *except* the `given` instance `tc`.
Conversely, the second import, `import A.given`, imports *only* that `given` instance.
The two `import` clauses can also be merged into one:

```scala
object B:
import A.{given, _}
import A.{given, *}
```

### Discussion

The wildcard selector `_` brings all definitions other than givens or extensions into scope, whereas a `given` selector brings all *givens*---including those resulting from extensions---into scope.
The wildcard selector `*` brings all definitions other than givens or extensions into scope, whereas a `given` selector brings all *givens*---including those resulting from extensions---into scope.

These rules have two main benefits:

Expand Down Expand Up @@ -368,7 +366,7 @@ object MonthConversions:
To import those givens into the current scope, use these two `import` statements:

```scala
import MonthConversions._
import MonthConversions.*
import MonthConversions.{given MonthConverter[?]}
```

Expand Down
4 changes: 2 additions & 2 deletions _overviews/scala3-book/scala-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ In regards to the first point, Java classes and libraries are used in Scala appl
For instance, in Scala you can read files with a Java `BufferedReader` and `FileReader`:

```scala
import java.io._
import java.io.*
val br = BufferedReader(FileReader(filename))
// read the file with `br` ...
```
Expand All @@ -280,7 +280,7 @@ 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:

```scala
import scala.jdk.CollectionConverters._
import scala.jdk.CollectionConverters.*
val scalaList: Seq[Integer] = JavaClass.getJavaList().asScala.toSeq
```

Expand Down
8 changes: 4 additions & 4 deletions _overviews/scala3-book/scala-for-javascript-devs.md
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ Dates are another commonly used type in both languages.
<tr>
<td class="scala-block">
<code>// different ways to get the current date and time
<br>import java.time._
<br>import java.time.*
<br>
<br>val a = LocalDate.now
<br>&nbsp;&nbsp;&nbsp; // 2020-11-29
Expand Down Expand Up @@ -561,9 +561,9 @@ enum Topping:

// import those enumerations and the ArrayBuffer,
// so the Pizza class can use them
import CrustSize._
import CrustType._
import Topping._
import CrustSize.*
import CrustType.*
import Topping.*
import scala.collection.mutable.ArrayBuffer

// define an OOP style Pizza class
Expand Down
2 changes: 1 addition & 1 deletion _overviews/scala3-book/taste-modeling.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ enum Topping:
Once you have an enum you can use it in all of the ways you normally use a trait, class, or object:

```scala
import CrustSize._
import CrustSize.*
val currentCrustSize = Small

// enums in a `match` expression
Expand Down
6 changes: 3 additions & 3 deletions _overviews/scala3-book/taste-objects.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ Use a companion object for methods and values which aren’t specific to instanc
This example demonstrates how the `area` method in the companion class can access the private `calculateArea` method in its companion object:

```scala
import scala.math._
import scala.math.*

class Circle(radius: Double):
import Circle._
import Circle.*
def area: Double = calculateArea(radius)

object Circle:
Expand Down Expand Up @@ -80,7 +80,7 @@ trait MultiplyService:
object MathService extends AddService, MultiplyService

// use the object
import MathService._
import MathService.*
println(add(1,1)) // 2
println(multiply(2,2)) // 4
```
Expand Down
2 changes: 1 addition & 1 deletion _overviews/scala3-book/taste-toplevel-definitions.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import scala.collection.mutable.ArrayBuffer
enum Topping:
case Cheese, Pepperoni, Mushrooms

import Topping._
import Topping.*
class Pizza:
val toppings = ArrayBuffer[Topping]()

Expand Down
4 changes: 2 additions & 2 deletions _overviews/scala3-book/types-opaque-types.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ Directly using `LogarithmsImpl` would make the equality `Logarithm = Double` vis
For example:

```scala
import LogarithmsImpl._
import LogarithmsImpl.*
val l: Logarithm = make(1.0)
val d: Double = l // type checks AND leaks the equality!
```
Expand Down Expand Up @@ -123,7 +123,7 @@ The type equality `Logarithm = Double` can be used to implement the methods (lik
However, outside of the module the type `Logarithm` is completely encapsulated, or “opaque.” To users of `Logarithm` it is not possible to discover that `Logarithm` is actually implemented as a `Double`:

```scala
import Logarithms._
import Logarithms.*
val l2 = Logarithm(2.0)
val l3 = Logarithm(3.0)
println((l2 * l3).toDouble) // prints 6.0
Expand Down
4 changes: 2 additions & 2 deletions _overviews/scala3-macros/tutorial/quotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ Though it looks like a splice takes an expression as argument, it actually takes
Therefore we could actually write it explicitly as `${ (using q) => ... }`, this might be useful when debugging to avoid generated names for these scopes.

The method `scala.quoted.quotes` provides a simple way to use the current `Quotes` without naming it.
It is usually imported along with the `Quotes` using `import scala.quoted._`.
It is usually imported along with the `Quotes` using `import scala.quoted.*`.

```scala
${ (using q1) => body(using q1) }
Expand Down Expand Up @@ -487,7 +487,7 @@ inline def setFor[T]: Set[T] =
${ setForCode[T] }

def setForCode[T: Type](using Quotes): Expr[Set[T]] =
import scala.collection.immutable._
import scala.collection.immutable.*
Expr.summon[Ordering[T]] match
case Some(ord) => '{ TreeSet.empty[T](using $ord) }
case _ => '{ HashSet.empty[T] }
Expand Down
2 changes: 1 addition & 1 deletion _overviews/scala3-macros/tutorial/reflection.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ We can use `scala.quoted.quotes` to import it.

```scala
def pow(x: Expr[Int])(using Quotes): Expr[Int] = {
import quotes.reflect._ // Import Tree, Type, Symbol, Position, .....
import quotes.reflect.* // Import Tree, Type, Symbol, Position, .....
...
}
```
Expand Down