Skip to content

Commit bf7cf83

Browse files
committed
Add support for snippet importing. Refactor docs to use new feature.
1 parent 3344e93 commit bf7cf83

File tree

14 files changed

+152
-258
lines changed

14 files changed

+152
-258
lines changed

docs/docs/reference/other-new-features/creator-applications.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,20 @@ function application, without needing to write `new`.
99

1010
Scala 3 generalizes this scheme to all concrete classes. Example:
1111

12-
```scala
12+
```scala sc-id:1
1313
class MyStringBuilder(s: String):
1414
def this() = this("")
15+
```
1516

17+
```scala sc-compile-with:1
1618
MyStringBuilder("abc") // old: new MyStringBuilder("abc")
1719
MyStringBuilder() // old: new MyStringBuilder()
1820
```
1921

2022
This works since a companion object with two `apply` methods
2123
is generated together with the class. The object looks like this:
2224

23-
```scala
24-
//{
25-
class MyStringBuilder(s: String):
26-
def this() = this("")
27-
//}
25+
```scala sc-compile-with:1
2826
object MyStringBuilder:
2927
inline def apply(s: String): MyStringBuilder = new MyStringBuilder(s)
3028
inline def apply(): MyStringBuilder = new MyStringBuilder()

docs/docs/reference/other-new-features/explicit-nulls.md

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -148,20 +148,16 @@ We illustrate the rules with following examples:
148148

149149
==>
150150

151-
```scala
151+
```scala sc-id:1
152152
class C[T] { def foo(): T | Null = null }
153153
```
154154

155155
Notice this is rule is sometimes too conservative, as witnessed by
156156

157-
```scala sc:fail
158-
//{
159-
class C[T] { def foo(): T | Null = null }
160-
type Bool
161-
//}
157+
```scala sc:fail sc-compile-with:1
162158
class InScala:
163-
val c: C[Bool] = ??? // C as above
164-
val b: Bool = c.foo() // no longer typechecks, since foo now returns Bool | Null
159+
val c: C[Boolean] = ??? // C as above
160+
val b: Boolean = c.foo() // no longer typechecks, since foo now returns Bool | Null
165161
```
166162

167163
- We can reduce the number of redundant nullable types we need to add. Consider
@@ -173,8 +169,11 @@ We illustrate the rules with following examples:
173169

174170
==>
175171

176-
```scala
172+
```scala sc-id:2
177173
abstract class Box[T] { def get(): T | Null }
174+
```
175+
176+
```scala sc-compile-with:2
178177
abstract class BoxFactory[T] { def makeBox(): Box[T] | Null }
179178
```
180179

@@ -199,10 +198,7 @@ We illustrate the rules with following examples:
199198

200199
==>
201200

202-
```scala
203-
//{
204-
abstract class Box[T] { def get(): T | Null }
205-
//}
201+
```scala sc-compile-with:2
206202
abstract class BoxFactory[T]:
207203
def makeBox(): Box[T | Null] | Null
208204
def makeCrazyBoxes(): java.util.List[Box[java.util.List[T] | Null]] | Null
@@ -232,7 +228,7 @@ We illustrate the rules with following examples:
232228

233229
```scala
234230
//{
235-
def getNewName(): String | Null = ???
231+
def getNewName(): String = ???
236232
//}
237233
class Constants:
238234
val NAME: String = "name"
@@ -255,10 +251,7 @@ We illustrate the rules with following examples:
255251

256252
==>
257253

258-
```scala
259-
//{
260-
abstract class Box[T] { def get(): T | Null }
261-
//}
254+
```scala sc-compile-with:2
262255
abstract class C:
263256
val name: String
264257
def getNames(prefix: String | Null): java.util.List[String] // we still need to nullify the paramter types

docs/docs/reference/other-new-features/export.md

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ movedTo: https://docs.scala-lang.org/scala3/reference/other-new-features/export.
66

77
An export clause defines aliases for selected members of an object. Example:
88

9-
```scala
9+
```scala sc-name:Model.scala
1010
class BitMap
1111
class InkJet
1212

@@ -39,29 +39,7 @@ final type PrinterType = printUnit.PrinterType
3939

4040
They can be accessed inside `Copier` as well as from outside:
4141

42-
```scala
43-
//{
44-
class BitMap
45-
class InkJet
46-
47-
class Printer:
48-
type PrinterType
49-
def print(bits: BitMap): Unit = ???
50-
def status: List[String] = ???
51-
52-
class Scanner:
53-
def scan(): BitMap = ???
54-
def status: List[String] = ???
55-
56-
class Copier:
57-
private val printUnit = new Printer { type PrinterType = InkJet }
58-
private val scanUnit = new Scanner
59-
60-
export scanUnit.scan
61-
export printUnit.{status => _, *}
62-
63-
def status: List[String] = printUnit.status ++ scanUnit.status
64-
//}
42+
```scala sc-compile-with:Model.scala
6543
val copier = new Copier
6644
copier.print(copier.scan())
6745
```
@@ -164,20 +142,19 @@ ImportSelectors ::= NamedSelector [‘,’ ImportSelectors]
164142
Export clauses raise questions about the order of elaboration during type checking.
165143
Consider the following example:
166144
167-
```scala
145+
```scala sc-id:1
168146
class B { val c: Int = ??? }
169147
object a { val b = new B }
148+
```
149+
150+
```scala sc-compile-with:1
170151
export a.*
171152
export b.*
172153
```
173154

174155
Is the `export b.*` clause legal? If yes, what does it export? Is it equivalent to `export a.b.*`? What about if we swap the last two clauses?
175156

176-
```scala sc:fail
177-
//{
178-
class B { val c: Int = ??? }
179-
object a { val b = new B }
180-
//}
157+
```scala sc:fail sc-compile-with:1
181158
export b.*
182159
export a.*
183160
```

docs/docs/reference/other-new-features/indentation-experimental.md

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,14 @@ IndentedArgument ::= indent (CaseClauses | Block) outdent
9292
Note that a lambda argument must have the `=>` at the end of a line for braces
9393
to be optional. For instance, the following would also be incorrect:
9494

95-
```scala sc:fail
96-
//{
97-
val xs: Seq[Int]
98-
//}
95+
```scala sc-id:1
96+
val xs: Seq[Int]
97+
```
98+
99+
```scala sc:fail sc-compile-with:1
99100
xs.map x => x + 1 // error: braces or parentheses are required
100101
```
101102
The lambda has to be enclosed in braces or parentheses:
102-
```scala
103-
//{
104-
val xs: Seq[Int]
105-
//}
103+
```scala sc-compile-with:1
106104
xs.map(x => x + 1) // ok
107105
```

docs/docs/reference/other-new-features/matchable.md

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ is guaranteed to succeed at run-time since `Any` and `Matchable` both erase to
120120

121121
For instance, consider the definitions
122122

123-
```scala
123+
```scala sc-id:1
124124
opaque type Meter = Double
125125
def Meter(x: Double) = x
126126

@@ -130,27 +130,13 @@ def Second(x: Double) = x
130130

131131
Here, universal `equals` will return true for
132132

133-
```scala
134-
//{
135-
opaque type Meter = Double
136-
def Meter(x: Double) = x
137-
138-
opaque type Second = Double
139-
def Second(x: Double) = x
140-
//}
133+
```scala sc-compile-with:1
141134
Meter(10).equals(Second(10))
142135
```
143136

144137
even though this is clearly false mathematically. With [multiversal equality](../contextual/multiversal-equality.md) one can mitigate that problem somewhat by turning
145138

146-
```scala
147-
//{
148-
opaque type Meter = Double
149-
def Meter(x: Double) = x
150-
151-
opaque type Second = Double
152-
def Second(x: Double) = x
153-
//}
139+
```scala sc-compile-with:1
154140
Meter(10) == Second(10)
155141
```
156142

docs/docs/reference/other-new-features/opaques.md

Lines changed: 7 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ movedTo: https://docs.scala-lang.org/scala3/reference/other-new-features/opaques
66

77
Opaque types aliases provide type abstraction without any overhead. Example:
88

9-
```scala
9+
```scala sc-id:1
1010
object MyMath:
1111

1212
opaque type Logarithm = Double
@@ -41,31 +41,7 @@ The public API of `Logarithm` consists of the `apply` and `safe` methods defined
4141
They convert from `Double`s to `Logarithm` values. Moreover, an operation `toDouble` that converts the other way, and operations `+` and `*` are defined as extension methods on `Logarithm` values.
4242
The following operations would be valid because they use functionality implemented in the `MyMath` object.
4343

44-
```scala
45-
//{
46-
object MyMath:
47-
48-
opaque type Logarithm = Double
49-
50-
object Logarithm:
51-
52-
// These are the two ways to lift to the Logarithm type
53-
54-
def apply(d: Double): Logarithm = math.log(d)
55-
56-
def safe(d: Double): Option[Logarithm] =
57-
if d > 0.0 then Some(math.log(d)) else None
58-
59-
end Logarithm
60-
61-
// Extension methods define opaque types' public APIs
62-
extension (x: Logarithm)
63-
def toDouble: Double = math.exp(x)
64-
def + (y: Logarithm): Logarithm = Logarithm(math.exp(x) + math.exp(y))
65-
def * (y: Logarithm): Logarithm = x + y
66-
67-
end MyMath
68-
//}
44+
```scala sc-compile-with:1
6945
import MyMath.Logarithm
7046

7147
val l = Logarithm(1.0)
@@ -76,31 +52,7 @@ val l4 = l + l2
7652

7753
But the following operations would lead to type errors:
7854

79-
```scala sc:fail
80-
//{
81-
object MyMath:
82-
83-
opaque type Logarithm = Double
84-
85-
object Logarithm:
86-
87-
// These are the two ways to lift to the Logarithm type
88-
89-
def apply(d: Double): Logarithm = math.log(d)
90-
91-
def safe(d: Double): Option[Logarithm] =
92-
if d > 0.0 then Some(math.log(d)) else None
93-
94-
end Logarithm
95-
96-
// Extension methods define opaque types' public APIs
97-
extension (x: Logarithm)
98-
def toDouble: Double = math.exp(x)
99-
def + (y: Logarithm): Logarithm = Logarithm(math.exp(x) + math.exp(y))
100-
def * (y: Logarithm): Logarithm = x + y
101-
102-
end MyMath
103-
//}
55+
```scala sc:fail sc-compile-with:1
10456
import MyMath.Logarithm
10557

10658
val l = Logarithm(1.0)
@@ -114,7 +66,7 @@ l / l2 // error: `/` is not a member of Logarithm
11466

11567
Opaque type aliases can also come with bounds. Example:
11668

117-
```scala
69+
```scala sc-id:2
11870
object Access:
11971

12072
opaque type Permissions = Int
@@ -161,31 +113,7 @@ All three opaque type aliases have the same underlying representation type `Int`
161113
it known outside the `Access` object that `Permission` is a subtype of the other
162114
two types. Hence, the following usage scenario type-checks.
163115

164-
```scala
165-
//{
166-
object Access:
167-
168-
opaque type Permissions = Int
169-
opaque type PermissionChoice = Int
170-
opaque type Permission <: Permissions & PermissionChoice = Int
171-
172-
extension (x: Permissions)
173-
def & (y: Permissions): Permissions = x | y
174-
extension (x: PermissionChoice)
175-
def | (y: PermissionChoice): PermissionChoice = x | y
176-
extension (granted: Permissions)
177-
def is(required: Permissions) = (granted & required) == required
178-
extension (granted: Permissions)
179-
def isOneOf(required: PermissionChoice) = (granted & required) != 0
180-
181-
val NoPermission: Permission = 0
182-
val Read: Permission = 1
183-
val Write: Permission = 2
184-
val ReadWrite: Permissions = Read | Write
185-
val ReadOrWrite: PermissionChoice = Read | Write
186-
187-
end Access
188-
//}
116+
```scala sc-compile-with:2
189117
object User:
190118
import Access.*
191119

@@ -214,7 +142,7 @@ since `Permissions` and `PermissionChoice` are different, unrelated types outsid
214142
While typically, opaque types are used together with objects to hide implementation details of a module, they can also be used with classes.
215143

216144
For example, we can redefine the above example of Logarithms as a class.
217-
```scala
145+
```scala sc-id:3
218146
class Logarithms:
219147

220148
opaque type Logarithm = Double
@@ -228,19 +156,7 @@ class Logarithms:
228156
```
229157

230158
Opaque type members of different instances are treated as different:
231-
```scala sc:fail
232-
//{
233-
class Logarithms:
234-
235-
opaque type Logarithm = Double
236-
237-
def apply(d: Double): Logarithm = math.log(d)
238-
239-
def safe(d: Double): Option[Logarithm] =
240-
if d > 0.0 then Some(math.log(d)) else None
241-
242-
def mul(x: Logarithm, y: Logarithm) = x + y
243-
//}
159+
```scala sc:fail sc-compile-with:3
244160
val l1 = new Logarithms
245161
val l2 = new Logarithms
246162
val x = l1(1.5)

0 commit comments

Comments
 (0)