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
map
method 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