Functions as First-Class Values
Learn to define and pass functions as arguments, return them from other functions, and store them in variables.
Functions as First-Class Values is a free Scala for Backend Engineering & Functional Programming lesson on CoddyKit — lesson 1 of 3. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Scala for Backend Engineering & Functional Programming learning path, one of 3 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Functions as First-Class Values
Welcome to Functional Programming Core! In Scala, functions are not just commands; they're first-class values.
This means you can treat functions just like any other data type, such as numbers or strings. This is a core concept in functional programming!
Assigning Functions to Variables
Just like you can assign a number to a val, you can assign a function to one. Here, greet becomes a variable holding our function.
Try running this simple example:
object Main {
def main(args: Array[String]): Unit = {
val greet = (name: String) => s"Hello, $name!"
println(greet("Alice"))
}
}Anonymous Functions (Lambdas)
The (name: String) => s"Hello, $name!" part in the previous scene is an anonymous function, also known as a lambda expression.
It's a function without a name, often defined inline where it's needed. They're super handy for quick, specific tasks.
object Main {
def main(args: Array[String]): Unit = {
val add = (x: Int, y: Int) => x + y
println(s"5 + 3 = ${add(5, 3)}")
val subtract = (a: Int, b: Int) => a - b
println(s"10 - 4 = ${subtract(10, 4)}")
}
}Functions as Method Arguments
One of the most powerful aspects is passing functions as arguments to other functions. These are called higher-order functions.
The applyOperation function below takes two numbers and another function op. op is then used to combine the numbers.
object Main {
def applyOperation(x: Int, y: Int, op: (Int, Int) => Int): Int = {
op(x, y)
}
def main(args: Array[String]): Unit = {
val add = (a: Int, b: Int) => a + b
val result = applyOperation(5, 3, add)
println(s"Result of addition: $result")
}
}Understanding Function Types
Notice the type signature op: (Int, Int) => Int in the previous scene.
(Int, Int): This means the function takes twoIntarguments.=> Int: This means the function returns anInt.
Every function has a type that describes its inputs and output. This helps Scala ensure type safety!
Concise Function Passing
You don't always need to define a named function first. You can pass an anonymous function directly where a function argument is expected.
This makes your code more compact and readable, especially for simple operations.
object Main {
def applyOperation(x: Int, y: Int, op: (Int, Int) => Int): Int = {
op(x, y)
}
def main(args: Array[String]): Unit = {
val result1 = applyOperation(10, 2, (a: Int, b: Int) => a * b)
println(s"Multiplication: $result1")
// Scala can often infer types, making it even shorter!
val result2 = applyOperation(20, 4, (a, b) => a / b)
println(s"Division: $result2")
}
}Functions as Return Values
Functions can also return other functions. This might sound mind-bending, but it's incredibly useful for creating flexible, configurable code.
Here, makeMultiplier returns a new function that multiplies its input by a specific factor.
object Main {
def makeMultiplier(factor: Int): Int => Int = {
(x: Int) => x * factor
}
def main(args: Array[String]): Unit = {
val multiplyByTwo = makeMultiplier(2)
val multiplyByFive = makeMultiplier(5)
println(s"5 * 2 = ${multiplyByTwo(5)}")
println(s"10 * 5 = ${multiplyByFive(10)}")
}
}Understanding Closures
When makeMultiplier returns a function, that returned function 'remembers' the factor value from when it was created. This is called a closure.
Even after makeMultiplier has finished executing, the multiplyByTwo function still 'knows' that its factor is 2.
Benefits of First-Class Functions
Why is treating functions as first-class citizens so important?
- Flexibility: You can easily swap out behaviors by passing different functions.
- Reusability: Build generic functions that operate on any function you provide.
- Conciseness: Leads to shorter, more expressive code, especially with anonymous functions.
- Functional Style: It's a cornerstone of functional programming, enabling powerful patterns.
Test Your Knowledge
Let's check your understanding of functions as first-class values.
object Main {
def execute(x: Int, op: Int => Int): Int = op(x)
def main(args: Array[String]): Unit = {
val square = (n: Int) => n * n
val result = execute(5, square)
println(result)
}
}Functions as Values: Recap
Great job! You've learned the fundamental concept of functions as first-class values in Scala.
- Functions can be assigned to variables.
- They can be passed as arguments to other functions.
- They can be returned as results from other functions.
- This enables powerful patterns like higher-order functions and closures.
This capability is key to writing flexible, reusable, and expressive functional Scala code. Up next, we'll dive into more advanced higher-order functions and currying!
Frequently asked questions
Is the “Functions as First-Class Values” lesson free?
Yes — the full text of “Functions as First-Class Values” is free to read here on the web, and the Scala for Backend Engineering & Functional Programming course includes 3 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Scala for Backend Engineering & Functional Programming course, upgrade to CoddyKit PRO.
What will I learn in “Functions as First-Class Values”?
Learn to define and pass functions as arguments, return them from other functions, and store them in variables. You practise Scala for Backend Engineering & Functional Programming with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Scala for Backend Engineering & Functional Programming?
No prior experience is required. Scala for Backend Engineering & Functional Programming on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 3, so you can start here or from the beginning and move at your own pace.
How long does the “Functions as First-Class Values” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Scala for Backend Engineering & Functional Programming lesson?
Yes. Every Scala for Backend Engineering & Functional Programming lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Functions as First-Class Values
- Higher-Order Functions & Currying
- Immutability and Side Effects