Dart Functional Programming: Cheat Sheet Essentials

Home » Dart » Dart Functional Programming: Cheat Sheet Essentials

Introduction to Functional Programming in Dart

Functional programming (FP) is a programming paradigm that treats computation as the evaluation of mathematical functions. In Dart, functional programming provides powerful tools for writing clean, concise, and predictable code.

Dart Functional Programming: Cheat Sheet Essentials

Key Functional Programming Concepts in Dart

1. First-Class and Higher-Order Functions

Dart treats functions as first-class citizens, allowing you to:

  • Assign functions to variables
  • Pass functions as arguments
  • Return functions from other functions

Function as a variable (Dart)

void main() 
{
  
 // using -1 
  
 print("Sum ${add(10,89)}"); //outputs: Sum 99
  
 // using - 2
  
 var double = mutliplier(2); 
 print(double(5));  //outputs: 10
  
}

// function as a variable -1 

Function add = (int a, int b) => a + b;


//Higher-order function -2 

Function mutliplier(int factor) {
  
  return (int number) => number * factor;
}

Output

Sum 99
10

2. Pure Functions (Dart)

Pure functions are deterministic and have no side effects:

  • Always produce the same output for the same input
  • Do not modify external state
  • Do not depend on external state

Open DartPad and Write the following program:

void main() 
{
  print(calculateSquare(6));  // outputs: 36

}

// Pure function example
int calculateSquare(int number) {
  return number * number;
}

3. Immutability

Dart supports immutability through final and const keywords:

void main() 
{
// Immutable list
final List<int> numbers = [1, 2, 3];

// Compile-time constant
const PI = 3.14159;




}

//impossible: PI = 4.0;
//impossible: numbers = [5,6,7,7];

Remember: Constant variable can’t be re-assigned. The final variable ‘numbers’ can only set once.

4. Lambda Functions and Arrow Syntax

Dart provides concise syntax for creating anonymous functions:

void main() 
{

  // Lambda function
var squares = [1, 2, 3].map((number) => number * number);
  
print(squares);  
}

Output

(1, 4, 9)

Functional Programming Techniques

Map, Filter, and Reduce

These higher-order functions are fundamental to functional programming:

void main() {
  // Map: Transform list elements
  var doubled = [1, 2, 3].map((x) => x * 2);

  // Filter: Select elements based on condition
  var evenNumbers = [1, 2, 3, 4].where((x) => x.isEven);

  // Reduce: Combine list elements
  var sum = [1, 2, 3].reduce((a, b) => a + b);
  
  print(doubled); // outputs (2,4,6)
  print(evenNumbers); // outputs (2,4)
  print(sum); // outputs 6
  
}

Output

(2, 4, 6)
(2, 4)
6

Recursion

Functional programming often uses recursion instead of loops:

int factorial(int n) {
  return n <= 1 ? 1 : n * factorial(n - 1);
}

void main() {
  
  print(factorial(3)); // outputs : 6
  
}

Function Composition

Combining multiple functions to create new functions:

Function compose(Function f, Function g) {
  return (x) => f(g(x));
}

void main() {
  var double = (int x) => x * 2;
  var square = (int x) => x * x;
  
  var doubleAndSquare = compose(square, double);
  
  print(doubleAndSquare(2)); //outputs 16 
}

Advanced Functional Programming Concepts

Currying (Dart)

Breaking down functions with multiple arguments into a series of functions:

Function curriedAdd(int a) {
  return (int b) => a + b;
}

void main() {
  var add5 = curriedAdd(5);
  print(add5(3)); // Outputs: 8
}

Lazy Evaluation

Dart supports lazy evaluation through iterables and generators:

Iterable<int> generateInfiniteSequence() sync* {
  int i = 0;
  while (true) {
    yield i++;
  }
}

void main() {
  var count = 0;
  for (var number in generateInfiniteSequence()) {
    print(number);
    count++;
    if (count >= 50) break; 
  }
}

Output

0
1
2
3
.
49

generateInfiniteSequence() remains the same: This function still generates an infinite sequence of numbers.

count variable: We introduce a count variable to keep track of how many numbers we’ve printed.

for loop with a break condition:

  • We iterate over the generateInfiniteSequence().
  • Inside the loop, we print the number.
  • We increment the count after each number is printed.
  • The if (count >= 50) break; line checks if we’ve printed 50 numbers. If we have, the break statement exits the loop, stopping the printing.

Best Practices

  1. Prefer immutable data structures
  2. Use pure functions when possible
  3. Minimize state mutations
  4. Leverage higher-order functions
  5. Use pattern matching and switch expressions

Performance Considerations

While functional programming offers many benefits, be mindful of:

  • Memory overhead of creating new objects
  • Potential performance impact of recursive functions
  • Garbage collection overhead

Verdict

Functional programming in Dart provides powerful tools for writing more predictable and maintainable code. By understanding and applying these concepts, you can write more elegant and efficient Dart applications.

You may also like...