0
# Core Language Features
1
2
Essential Scala language constructs and basic functionality adapted for JavaScript execution, providing the foundation for Scala.js applications.
3
4
## Capabilities
5
6
### App Trait
7
8
Provides a simplified way to create executable programs without writing an explicit main method, automatically handling program initialization and command-line arguments.
9
10
```scala { .api }
11
/**
12
* Trait that provides a main method and automatic initialization for simple programs
13
* Uses DelayedInit to ensure proper initialization order in JavaScript environment
14
*/
15
trait App extends DelayedInit {
16
/** Command-line arguments passed to the program */
17
val args: Array[String]
18
19
/** Timestamp when program execution started (milliseconds since Unix epoch) */
20
val executionStart: Long
21
22
/** Called by DelayedInit mechanism for proper initialization */
23
def delayedInit(x: => Unit): Unit
24
}
25
```
26
27
**Usage Examples:**
28
29
```scala
30
// Simple executable program
31
object HelloWorld extends App {
32
println("Hello, World!")
33
println(s"Started at: $executionStart")
34
if (args.nonEmpty) {
35
println(s"Arguments: ${args.mkString(", ")}")
36
}
37
}
38
39
// Program with argument processing
40
object Calculator extends App {
41
if (args.length >= 3) {
42
val a = args(0).toDouble
43
val op = args(1)
44
val b = args(2).toDouble
45
46
val result = op match {
47
case "+" => a + b
48
case "-" => a - b
49
case "*" => a * b
50
case "/" => a / b
51
case _ => throw new IllegalArgumentException(s"Unknown operator: $op")
52
}
53
54
println(s"$a $op $b = $result")
55
} else {
56
println("Usage: Calculator <num1> <op> <num2>")
57
}
58
}
59
```
60
61
### Array Object
62
63
Comprehensive array creation and manipulation utilities providing all standard Scala array operations optimized for JavaScript.
64
65
```scala { .api }
66
/**
67
* Factory methods and utilities for creating and manipulating arrays
68
*/
69
object Array {
70
/** Create array from variable number of arguments */
71
def apply[T](xs: T*): Array[T]
72
73
/** Create 1D array with specified dimensions */
74
def ofDim[T: ClassTag](n1: Int): Array[T]
75
/** Create 2D array with specified dimensions */
76
def ofDim[T: ClassTag](n1: Int, n2: Int): Array[Array[T]]
77
/** Create 3D array with specified dimensions */
78
def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int): Array[Array[Array[T]]]
79
/** Create 4D array with specified dimensions */
80
def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int): Array[Array[Array[Array[T]]]]
81
/** Create 5D array with specified dimensions */
82
def ofDim[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int): Array[Array[Array[Array[Array[T]]]]]
83
84
/** Create empty array of specified type */
85
def empty[T: ClassTag]: Array[T]
86
87
/** Create array filled with specified element (call-by-name for lazy evaluation) */
88
def fill[T: ClassTag](n: Int)(elem: => T): Array[T]
89
/** Create 2D array filled with specified element */
90
def fill[T: ClassTag](n1: Int, n2: Int)(elem: => T): Array[Array[T]]
91
92
/** Create array by applying function to indices */
93
def tabulate[T: ClassTag](n: Int)(f: Int => T): Array[T]
94
/** Create 2D array by applying function to indices */
95
def tabulate[T: ClassTag](n1: Int, n2: Int)(f: (Int, Int) => T): Array[Array[T]]
96
97
/** Create array of integers in specified range (exclusive end) */
98
def range(start: Int, end: Int): Array[Int]
99
/** Create array of integers in specified range with step */
100
def range(start: Int, end: Int, step: Int): Array[Int]
101
102
/** Concatenate multiple arrays into single array */
103
def concat[T: ClassTag](xss: Array[T]*): Array[T]
104
105
/** Create array by iterating function from start value */
106
def iterate[T: ClassTag](start: T, len: Int)(f: T => T): Array[T]
107
108
/** Copy elements between arrays */
109
def copy(src: AnyRef, srcPos: Int, dest: AnyRef, destPos: Int, length: Int): Unit
110
111
/** Create new array builder for efficient array construction */
112
def newBuilder[T: ClassTag]: ArrayBuilder[T]
113
}
114
```
115
116
**Pre-defined Empty Arrays:**
117
118
```scala { .api }
119
object Array {
120
/** Pre-allocated empty arrays for primitive types (performance optimization) */
121
val emptyBooleanArray: Array[Boolean]
122
val emptyByteArray: Array[Byte]
123
val emptyCharArray: Array[Char]
124
val emptyDoubleArray: Array[Double]
125
val emptyFloatArray: Array[Float]
126
val emptyIntArray: Array[Int]
127
val emptyLongArray: Array[Long]
128
val emptyShortArray: Array[Short]
129
val emptyObjectArray: Array[Object]
130
}
131
```
132
133
**Usage Examples for Empty Arrays:**
134
135
```scala
136
import scala.Array
137
138
// Use pre-allocated empty arrays for better performance
139
val emptyInts = Array.emptyIntArray // Better than Array[Int]()
140
val emptyStrings = Array.emptyObjectArray.asInstanceOf[Array[String]]
141
142
// Efficient initialization in data structures
143
class IntBuffer {
144
private var data: Array[Int] = Array.emptyIntArray
145
146
def add(value: Int): Unit = {
147
if (data.length == 0) {
148
data = Array(value) // Allocate when needed
149
}
150
// ... rest of implementation
151
}
152
}
153
154
// Return empty arrays from functions without allocation
155
def filterPositive(numbers: Array[Int]): Array[Int] = {
156
val positive = numbers.filter(_ > 0)
157
if (positive.isEmpty) Array.emptyIntArray else positive
158
}
159
160
// Type-specific empty arrays avoid boxing overhead
161
def processDoubles(input: Option[Array[Double]]): Array[Double] = {
162
input.getOrElse(Array.emptyDoubleArray) // No boxing of primitive doubles
163
}
164
```
165
166
**Basic Array Creation:**
167
168
```scala
169
import scala.Array
170
171
// Basic array creation
172
val fruits = Array("apple", "banana", "cherry")
173
val numbers = Array(1, 2, 3, 4, 5)
174
175
// Multi-dimensional arrays
176
val matrix = Array.ofDim[Int](3, 3)
177
val cube = Array.ofDim[Double](2, 2, 2)
178
179
// Filled arrays
180
val zeros = Array.fill(10)(0)
181
val randomNumbers = Array.fill(5)(scala.util.Random.nextInt(100))
182
183
// Function-generated arrays
184
val squares = Array.tabulate(10)(i => i * i)
185
val multiplication = Array.tabulate(5, 5)((i, j) => i * j)
186
187
// Range arrays
188
val oneToTen = Array.range(1, 11)
189
val evens = Array.range(0, 20, 2)
190
191
// Array concatenation
192
val combined = Array.concat(
193
Array(1, 2, 3),
194
Array(4, 5, 6),
195
Array(7, 8, 9)
196
)
197
198
// Array iteration
199
val powers = Array.iterate(2, 8)(_ * 2) // Powers of 2: [2, 4, 8, 16, ...]
200
201
// Array copying
202
val source = Array(1, 2, 3, 4, 5)
203
val dest = Array.ofDim[Int](10)
204
Array.copy(source, 0, dest, 2, source.length) // Copy to middle of dest
205
```
206
207
### Symbol Class
208
209
Interned string representation providing memory-efficient string constants and pattern matching support.
210
211
```scala { .api }
212
/**
213
* Immutable interned strings for efficient symbol representation
214
* Symbols with the same name share the same instance (flyweight pattern)
215
*/
216
case class Symbol private (name: String) {
217
/** String representation with leading apostrophe */
218
override def toString: String = s"'$name"
219
}
220
221
object Symbol {
222
/** Create or retrieve interned symbol for given name */
223
def apply(name: String): Symbol
224
}
225
```
226
227
**Usage Examples:**
228
229
```scala
230
// Symbol creation
231
val greeting = Symbol("hello")
232
val status = Symbol("ok")
233
val error = Symbol("error")
234
235
// Symbol comparison (reference equality due to interning)
236
val sym1 = Symbol("test")
237
val sym2 = Symbol("test")
238
assert(sym1 eq sym2) // Same object reference
239
240
// Pattern matching with symbols
241
def processStatus(status: Symbol): String = status match {
242
case Symbol("ok") => "Success"
243
case Symbol("error") => "Failed"
244
case Symbol("pending") => "In Progress"
245
case _ => "Unknown"
246
}
247
248
// Using symbols as keys (efficient due to interning)
249
val statusMap = Map(
250
Symbol("active") -> "Running",
251
Symbol("inactive") -> "Stopped",
252
Symbol("maintenance") -> "Under Maintenance"
253
)
254
```
255
256
### Enumeration Class
257
258
Support for creating enumerated types with named constants and iteration capabilities.
259
260
```scala { .api }
261
/**
262
* Base class for creating enumerated types with named values
263
* Provides automatic ID assignment and iteration support
264
*/
265
abstract class Enumeration {
266
/** Base type for enumeration values */
267
type Value = EnumerationValue
268
269
/** Create enumeration value with auto-assigned ID */
270
protected final def Value: Value
271
/** Create enumeration value with specific ID */
272
protected final def Value(i: Int): Value
273
/** Create enumeration value with name and auto-assigned ID */
274
protected final def Value(name: String): Value
275
/** Create enumeration value with specific ID and name */
276
protected final def Value(i: Int, name: String): Value
277
278
/** Set of all values in this enumeration */
279
def values: ValueSet
280
281
/** Apply method to get value by ID */
282
def apply(x: Int): Value
283
284
/** Iterator over all values */
285
def iterator: Iterator[Value]
286
287
/** String representation of enumeration */
288
override def toString: String
289
}
290
```
291
292
**Usage Examples:**
293
294
```scala
295
// Basic enumeration
296
object Color extends Enumeration {
297
val Red, Green, Blue = Value
298
}
299
300
// Named enumeration values
301
object Status extends Enumeration {
302
val Pending = Value("pending")
303
val Processing = Value("processing")
304
val Complete = Value("complete")
305
val Failed = Value("failed")
306
}
307
308
// Enumeration with custom IDs
309
object Priority extends Enumeration {
310
val Low = Value(1, "low")
311
val Medium = Value(5, "medium")
312
val High = Value(10, "high")
313
val Critical = Value(20, "critical")
314
}
315
316
// Using enumerations
317
val currentColor = Color.Red
318
val taskStatus = Status.Processing
319
320
// Pattern matching
321
def getColorHex(color: Color.Value): String = color match {
322
case Color.Red => "#FF0000"
323
case Color.Green => "#00FF00"
324
case Color.Blue => "#0000FF"
325
}
326
327
// Iteration over enum values
328
println("Available colors:")
329
for (color <- Color.values) {
330
println(s"${color.id}: ${color}")
331
}
332
333
// Lookup by ID
334
val priorityById = Priority(10) // Returns Priority.High
335
```
336
337
### Package-Level Utilities
338
339
Core package-level functions and type aliases that provide foundational functionality.
340
341
```scala { .api }
342
/**
343
* Package-level utility functions and type aliases
344
* Available in scala package object
345
*/
346
347
// Type aliases for common types (Scala 2.13 specific)
348
type LazyList[+A] = scala.collection.immutable.LazyList[A]
349
type ::[A] = scala.collection.immutable.::[A]
350
351
// Utility functions for common operations
352
def identity[A](x: A): A = x
353
def implicitly[T](implicit e: T): T = e
354
def locally[T](x: T): T = x
355
356
// Assertion functions
357
def assert(assertion: Boolean): Unit
358
def assert(assertion: Boolean, message: => Any): Unit
359
def assume(assumption: Boolean): Unit
360
def assume(assumption: Boolean, message: => Any): Unit
361
362
// Require functions for preconditions
363
def require(requirement: Boolean): Unit
364
def require(requirement: Boolean, message: => Any): Unit
365
```
366
367
**Usage Examples:**
368
369
```scala
370
// Identity function
371
val x = identity(42) // x == 42
372
val list = List(1, 2, 3).map(identity) // Returns same list
373
374
// Implicit parameter access
375
def printType[T](value: T)(implicit manifest: Manifest[T]): Unit = {
376
val m = implicitly[Manifest[T]]
377
println(s"$value has type ${m.runtimeClass.getSimpleName}")
378
}
379
380
// Local block evaluation
381
val result = locally {
382
val a = 10
383
val b = 20
384
a + b
385
} // result == 30
386
387
// Assertions and requirements
388
def divide(a: Double, b: Double): Double = {
389
require(b != 0, "Division by zero")
390
assert(a.isFinite && b.isFinite, "Arguments must be finite")
391
a / b
392
}
393
394
// Assumption checking (for optimization)
395
def optimizedSort(arr: Array[Int]): Array[Int] = {
396
assume(arr.length < 1000, "Algorithm optimized for small arrays")
397
arr.sorted
398
}
399
```
400
401
### Console Operations
402
403
Console I/O operations adapted for JavaScript environment, providing standard output and input capabilities.
404
405
```scala { .api }
406
/**
407
* Console I/O operations for JavaScript environment
408
* Provides standard input/output operations using JavaScript console and DOM APIs
409
*/
410
object Console {
411
/** Print object to console without newline */
412
def print(obj: Any): Unit
413
414
/** Print object to console with newline */
415
def println(obj: Any): Unit = println(obj.toString)
416
def println(): Unit
417
418
/** Print formatted string to console */
419
def printf(text: String, args: Any*): Unit
420
421
/** Read line from standard input (JavaScript prompt or Node.js stdin) */
422
def readLine(): String
423
def readLine(text: String): String
424
425
/** Error output operations */
426
def err: java.io.PrintStream
427
428
/** Input operations */
429
def in: java.io.BufferedReader
430
431
/** Output operations */
432
def out: java.io.PrintStream
433
}
434
```
435
436
**Usage Examples:**
437
438
```scala
439
import scala.Console
440
441
// Basic output
442
Console.println("Hello, Scala.js!")
443
Console.print("No newline: ")
444
Console.println("With newline")
445
446
// Formatted output
447
Console.printf("Number: %d, String: %s%n", 42, "test")
448
449
// Interactive input (browser environment)
450
val name = Console.readLine("Enter your name: ")
451
Console.println(s"Hello, $name!")
452
453
// Using implicit operations
454
println("Direct println call") // Uses Console.println implicitly
455
456
// Error output
457
Console.err.println("This goes to error stream")
458
```