Skip to content

Scala Basic Syntax

This chapter introduces the basic syntax rules of Scala, including program structure, comments, identifiers, keywords, and other core concepts.

Program Structure

Hello World Program

Let's start with the classic Hello World program:

scala
// Scala 3 style (recommended)
@main def hello(): Unit =
  println("Hello, World!")

// Or traditional main method
object HelloWorld {
  def main(args: Array[String]): Unit = {
    println("Hello, World!")
  }
}

Program Components

A Scala program typically contains the following parts:

  1. Package declaration (optional)
  2. Import statements (optional)
  3. Class, object, trait definitions
  4. Method and function definitions
scala
// 1. Package declaration
package com.example.myapp

// 2. Import statements
import scala.collection.mutable.ListBuffer
import java.util.Date

// 3. Object definition
object MyApp {
  // 4. Method definition
  def main(args: Array[String]): Unit = {
    println("My Scala Application")
  }
}

Comments

Scala supports three types of comments:

Single-line Comments

scala
// This is a single-line comment
val x = 10  // End of line comment

Multi-line Comments

scala
/*
 * This is a multi-line comment
 * Can span multiple lines
 */
val y = 20

/* Simple multi-line comment */

Documentation Comments

scala
/**
 * This is a documentation comment for generating API documentation
 * @param name Username
 * @param age Age
 * @return Formatted user information
 */
def formatUser(name: String, age: Int): String = {
  s"User: $name, Age: $age"
}

Identifiers

Identifiers are used to name variables, methods, classes, and other program elements.

Identifier Rules

  1. Alphanumeric identifiers: Start with a letter or underscore, followed by letters, numbers, or underscores
scala
val name = "Alice"
val user_age = 25
val MAX_SIZE = 100
val _private = "hidden"
  1. Operator identifiers: Consist of operator characters
scala
val + = "plus"
val :: = "cons"
val <=> = "compare"
  1. Mixed identifiers: Alphanumeric identifier followed by underscore and operator identifier
scala
val unary_+ = "positive"
val myList_+ = "append"
  1. Literal identifiers: Any string enclosed in backticks
scala
val `class` = "reserved word"
val `my variable` = "with spaces"
val `2nd-item` = "starts with number"

Naming Conventions

scala
// Variables and methods: camelCase
val firstName = "John"
def calculateTotal() = 100

// Constants: uppercase letters and underscores
val MAX_RETRY_COUNT = 3
val DEFAULT_TIMEOUT = 30

// Classes and traits: PascalCase
class UserAccount
trait Serializable

// Packages: lowercase
package com.example.utils

Keywords

Scala's reserved keywords cannot be used as identifiers:

Basic Keywords

scala
abstract    case        catch       class       def
do          else        extends     false       final
finally     for         if          implicit    import
lazy        match       new         null        object
override    package     private     protected   return
sealed      super       this        throw       trait
try         true        type        val         var
while       with        yield

Scala 3 New Keywords

scala
enum        export      given       then        using

Soft Keywords

These have special meaning in specific contexts:

scala
as          derives     end         extension   infix
inline      opaque      open        transparent using

Literals

Integer Literals

scala
val decimal = 123        // Decimal
val hex = 0xFF          // Hexadecimal
val octal = 0o77        // Octal (Scala 3)
val binary = 0b1010     // Binary (Scala 3)
val long = 123L         // Long type

Floating-point Literals

scala
val double1 = 3.14
val double2 = 1.23e-4   // Scientific notation
val float = 3.14f       // Float type
val double3 = 3.14d     // Explicit Double type

Character Literals

scala
val char1 = 'A'
val char2 = '\n'        // Newline character
val char3 = '\u0041'    // Unicode character 'A'

String Literals

scala
// Regular string
val str1 = "Hello, World!"

// String with escape characters
val str2 = "Line 1\nLine 2\tTabbed"

// Raw string (triple quotes)
val str3 = """This is a
             |multi-line
             |string""".stripMargin

// String interpolation
val name = "Alice"
val age = 25
val str4 = s"Name: $name, Age: $age"
val str5 = s"Next year: ${age + 1}"

// Formatted string
val str6 = f"Pi is approximately ${math.Pi}%.2f"

// Raw string interpolation
val path = raw"C:\Users\$name\Documents"

Boolean Literals

scala
val isTrue = true
val isFalse = false

Symbol Literals

scala
val symbol1 = Symbol("name")
val symbol2 = 'name  // Shorthand form (deprecated)

Operators

Arithmetic Operators

scala
val a = 10
val b = 3

val sum = a + b        // 13
val diff = a - b       // 7
val product = a * b    // 30
val quotient = a / b   // 3
val remainder = a % b  // 1

Relational Operators

scala
val x = 5
val y = 10

val equal = x == y      // false
val notEqual = x != y   // true
val less = x < y        // true
val greater = x > y     // false
val lessEqual = x <= y  // true
val greaterEqual = x >= y // false

Logical Operators

scala
val p = true
val q = false

val and = p && q        // false
val or = p || q         // true
val not = !p            // false

Bitwise Operators

scala
val a = 12  // 1100 in binary
val b = 10  // 1010 in binary

val bitwiseAnd = a & b  // 8 (1000)
val bitwiseOr = a | b   // 14 (1110)
val bitwiseXor = a ^ b  // 6 (0110)
val bitwiseNot = ~a     // -13
val leftShift = a << 1  // 24
val rightShift = a >> 1 // 6

Assignment Operators

scala
var x = 10
x += 5    // x = x + 5, result is 15
x -= 3    // x = x - 3, result is 12
x *= 2    // x = x * 2, result is 24
x /= 4    // x = x / 4, result is 6
x %= 4    // x = x % 4, result is 2

Expressions and Statements

Expressions

In Scala, almost everything is an expression (has a return value):

scala
// Simple expression
val result1 = 2 + 3  // 5

// Conditional expression
val result2 = if (x > 0) "positive" else "non-positive"

// Block expression
val result3 = {
  val a = 10
  val b = 20
  a + b  // Last expression in block is the return value
}

// Method call expression
val result4 = "hello".toUpperCase()

Statements vs Expressions

scala
// Expressions (have return values)
val x = 42                    // Returns Unit
val y = if (x > 0) 1 else 0  // Returns Int

// Statements (mainly for side effects)
println("Hello")              // Returns Unit
var counter = 0
counter += 1                  // Returns Unit

Code Blocks and Scope

Code Blocks

scala
val result = {
  val x = 10
  val y = 20
  val z = x + y
  z * 2  // Block's return value
}  // result = 60

Scope Rules

scala
val outer = "outer"

def example(): Unit = {
  val inner = "inner"

  {
    val nested = "nested"
    println(outer)   // Can access
    println(inner)   // Can access
    println(nested)  // Can access
  }

  // println(nested)  // Error: nested is out of scope
}

Method Definition Syntax

Basic Method Definition

scala
// With parameters and return type
def add(x: Int, y: Int): Int = {
  x + y
}

// Simplified form (single expression)
def multiply(x: Int, y: Int): Int = x * y

// No parameter method
def getCurrentTime(): Long = System.currentTimeMillis()

// No parameter method (parentheses can be omitted)
def pi: Double = 3.14159

Method Parameters

scala
// Default parameters
def greet(name: String, greeting: String = "Hello"): String = {
  s"$greeting, $name!"
}

// Named parameter calls
val message1 = greet("Alice")
val message2 = greet("Bob", "Hi")
val message3 = greet(greeting = "Hey", name = "Charlie")

// Variable parameters
def sum(numbers: Int*): Int = {
  numbers.sum
}

val total = sum(1, 2, 3, 4, 5)

Type Annotations

Variable Type Annotations

scala
// Explicit type annotation
val name: String = "Alice"
val age: Int = 25
val height: Double = 5.6

// Type inference (recommended)
val name2 = "Bob"        // Inferred as String
val age2 = 30           // Inferred as Int
val height2 = 5.8       // Inferred as Double

Method Type Annotations

scala
// Return type annotation
def calculate(x: Int, y: Int): Int = x + y

// Complex type annotation
def processData(data: List[String]): Map[String, Int] = {
  data.groupBy(identity).view.mapValues(_.length).toMap
}

Import Statements

Basic Imports

scala
import scala.collection.mutable.ListBuffer
import java.util.Date
import java.io.{File, FileReader}  // Import multiple classes

Wildcard Imports

scala
import scala.collection.mutable._  // Import everything in package
import java.util.{Date, Calendar, _}  // Import specified classes and everything else

Renaming Imports

scala
import java.util.{Date => JavaDate}
import scala.collection.mutable.{Map => MutableMap}

val now = new JavaDate()
val map = MutableMap[String, Int]()

Hiding Imports

scala
import java.util.{Date => _, _}  // Import everything except Date

Relative Imports

scala
package com.example.app

import model._           // Import com.example.app.model package
import util.StringUtils  // Import com.example.app.util.StringUtils

Package Declarations

Basic Package Declaration

scala
package com.example.myapp

class MyClass {
  // Class definition
}

Nested Packages

scala
package com.example {
  package myapp {
    class MyClass
  }

  package utils {
    class Helper
  }
}

Package Objects

scala
package object myapp {
  val VERSION = "1.0.0"
  def utility(): String = "helper function"
}

// Can be used directly within package
package myapp
class MyClass {
  println(VERSION)  // Direct access to package object members
}

Exercises

Exercise 1: Basic Syntax

Create a program containing the following:

scala
// 1. Define a calculator object
object Calculator {

  // 2. Define basic operation methods
  def add(a: Double, b: Double): Double = a + b
  def subtract(a: Double, b: Double): Double = a - b
  def multiply(a: Double, b: Double): Double = a * b
  def divide(a: Double, b: Double): Double = {
    if (b != 0) a / b
    else throw new IllegalArgumentException("Division by zero")
  }

  // 3. Main method
  def main(args: Array[String]): Unit = {
    val x = 10.0
    val y = 3.0

    println(s"$x + $y = ${add(x, y)}")
    println(s"$x - $y = ${subtract(x, y)}")
    println(s"$x * $y = ${multiply(x, y)}")
    println(s"$x / $y = ${divide(x, y)}")
  }
}

Exercise 2: String Processing

scala
object StringProcessor {
  def processText(text: String): Unit = {
    // Use string interpolation
    println(s"Original: $text")
    println(s"Length: ${text.length}")
    println(s"Uppercase: ${text.toUpperCase}")
    println(s"Lowercase: ${text.toLowerCase}")

    // Use raw strings
    val pattern = raw"\d+"
    println(s"Pattern: $pattern")

    // Use formatted strings
    val percentage = 0.856
    println(f"Percentage: ${percentage * 100}%.2f%%")
  }

  def main(args: Array[String]): Unit = {
    processText("Hello, Scala World!")
  }
}

Summary

This chapter introduced Scala's basic syntax, including:

  • Program Structure: Package declarations, imports, class/object definitions
  • Comments: Single-line, multi-line, documentation comments
  • Identifiers: Naming rules and conventions
  • Literals: Literal representations of various data types
  • Operators: Arithmetic, relational, logical, bitwise operators
  • Expressions: Scala's expression-oriented feature
  • Method Definitions: Basic syntax and parameter handling
  • Type System: Type annotations and inference
  • Imports and Packages: Organizing code modularly

Mastering these basic syntax rules is an important foundation for learning Scala. In the next chapter, we will dive deep into Scala Data Types to understand Scala's rich type system.

Content is for learning and research only.