Scala has most features you’d expect in a functional programming language, including:
- Lambdas (anonymous functions)
- Higher-order functions (HOFs)
- Immutable collections in the standard library
Lambdas, also known as anonymous functions, are a big part of keeping your code concise but readable.
The map method of the List class is a typical example of a higher-order function—a function that takes a function as parameter.
These two examples are equivalent, and show how to multiply each number in a list by 2 by passing a lambda into the map method:
val a = List(1, 2, 3).map(i => i * 2) // List(2,4,6)
val b = List(1, 2, 3).map(_ * 2) // List(2,4,6)
Those examples are also equivalent to the following code, which uses a double method instead of a lambda:
def double(i: Int): Int = i * 2
val a = List(1, 2, 3).map(i => double(i)) // List(2,4,6)
val b = List(1, 2, 3).map(double) // List(2,4,6)
If you haven’t seen the
mapmethod before, it applies a given function to every element in a list, yielding a new list that contains the resulting values.
Passing lambdas to higher-order functions on collections classes (like List) is a part of the Scala experience, something you’ll do every day.
Immutable collections
When you work with immutable collections like List, Vector, and the immutable Map and Set classes, it’s important to know that these functions don’t mutate the collection they’re called on; instead, they return a new collection with the updated data.
As a result, it’s also common to chain them together in a “fluent” style to solve problems.
For instance, this example shows how to filter a collection twice, and then multiply each element in the remaining collection:
// a sample list
val nums = (1 to 10).toList // List(1,2,3,4,5,6,7,8,9,10)
// methods can be chained together as needed
val x = nums.filter(_ > 3)
.filter(_ < 7)
.map(_ * 10)
// result: x == List(40, 50, 60)
In addition to higher-order functions being used throughout the standard library, you can also create your own.
Contributors to this page:
Contents
- Introduction
- Scala Features
- Why Scala 3?
- A Taste of Scala
- Hello, World!
- The REPL
- Variables and Data Types
- Control Structures
- Domain Modeling
- Methods
- First-Class Functions
- Singleton Objects
- Collections
- Contextual Abstractions
- Toplevel Definitions
- Summary
- A First Look at Types
- String Interpolation
- Control Structures
- Domain Modeling
- Tools
- OOP Modeling
- FP Modeling
- Methods
- Method Features
- Main Methods in Scala 3
- Summary
- Functions
- Anonymous Functions
- Function Variables
- Partial Functions
- Eta-Expansion
- Higher-Order Functions
- Write Your Own map Method
- Creating a Method That Returns a Function
- Summary
- Packaging and Imports
- Scala Collections
- Collections Types
- Collections Methods
- Summary
- Functional Programming
- What is Functional Programming?
- Immutable Values
- Pure Functions
- Functions Are Values
- Functional Error Handling
- Summary
- Types and the Type System
- Inferred Types
- Generics
- Intersection Types
- Union Types
- Algebraic Data Types
- Variance
- Opaque Types
- Structural Types
- Dependent Function Types
- Other Types
- Contextual Abstractions
- Extension Methods
- Context Parameters
- Context Bounds
- Given Imports
- Type Classes
- Multiversal Equality
- Implicit Conversions
- Summary
- Concurrency
- Scala Tools
- Building and Testing Scala Projects with sbt
- Worksheets
- Interacting with Java
- Scala for Java Developers
- Scala for JavaScript Developers
- Scala for Python Developers
- Where To Go Next