dartfungsicallbackMenengah4 mnt baca

Higher-Order Function

Fungsi yang menerima atau mengembalikan fungsi lain: callback dan strategi.

Fungsi sebagai warga kelas satu

Di Dart, fungsi bukan warga kelas dua: ia bisa disimpan di variabel, dioper sebagai argumen, dan dikembalikan dari fungsi lain. Fungsi yang melakukan salah satu dari itu disebut higher-order function.

Analogi: resep masakan biasanya tetap, tapi kamu bisa mengganti "bumbu"nya. Higher-order function adalah resep yang bumbunya (perilaku) bisa diganti-ganti lewat parameter fungsi.

Kenapa higher-order function ada?

Karena ia memisahkan kerangka dari detail. Contoh: fungsi prosesData tahu cara loop dan validasi, tapi "apa yang dilakukan per item" diserahkan ke fungsi parameter. Satu kerangka, tak terbatas variasi perilaku, tanpa duplikasi.

Fungsi sebagai parameter (callback)

dart
// Menerima fungsi sebagai parameter
void proses(int a, int b, int Function(int, int) operasi) {
  var hasil = operasi(a, b);
  print('Hasil: $hasil');
}

int tambah(int x, int y) => x + y;
int kali(int x, int y) => x * y;

void main() {
  proses(6, 3, tambah); // Hasil: 9
  proses(6, 3, kali);   // Hasil: 18
  proses(6, 3, (x, y) => x - y); // Hasil: 3, anonim langsung
}

Tipe int Function(int, int) dibaca: "fungsi yang menerima dua int dan mengembalikan int". Satu fungsi proses, tiga perilaku berbeda.

Contoh kedua, pola yang sangat umum: eksekusi dengan retry:

dart
Future<T> denganRetry<T>(Future<T> Function() aksi, {int maks = 3}) async {
  for (int i = 1; i <= maks; i++) {
    try {
      return await aksi();
    } catch (e) {
      print('Percobaan $i gagal: $e');
      if (i == maks) rethrow;
    }
  }
  throw StateError('tidak tercapai');
}

Future<String> ambilData() async {
  await Future.delayed(Duration(milliseconds: 100));
  return 'OK';
}

Future<void> main() async {
  var hasil = await denganRetry(ambilData);
  print(hasil);
}

denganRetry tidak tahu apa aksinya; ia hanya tahu "coba sampai 3 kali". Logika retry ditulis sekali, dipakai untuk semua operasi async.

Fungsi yang mengembalikan fungsi

dart
// Membuat fungsi baru dengan "pengali" terkunci
int Function(int) buatPengali(int faktor) {
  return (int n) => n * faktor;
}

void main() {
  var kaliDua = buatPengali(2);
  var kaliSepuluh = buatPengali(10);

  print(kaliDua(5));     // 10
  print(kaliSepuluh(5)); // 50
}

buatPengali(2) menghasilkan fungsi baru yang "mengingat" faktor 2. Ini disebut currying parsial, berguna untuk membuat varian fungsi terkonfigurasi.

Kesalahan umum

1. Lupa tanda kurung saat mengoper fungsi

dart
// SALAH: tambah() langsung DIEKSEKUSI, hasilnya yang dioper
void main() {
  // proses(6, 3, tambah(?, ?)); // tidak masuk akal
}
dart
// BENAR: tanpa kurung = oper fungsinya sendiri
void main() {
  proses(6, 3, tambah);
}

tambah = fungsinya, tambah(1, 2) = hasilnya. Untuk callback, oper tanpa kurung.

2. Tipe fungsi tidak cocok

dart
// SALAH
void proses(int Function(int, int) op) {}
// proses((x) => x * 2); // ERROR: butuh 2 parameter
dart
// BENAR
void main() {
  proses((x, y) => x * y);
}

void proses(int Function(int, int) op) {
  print(op(3, 4));
}

3. Typedef untuk tipe fungsi panjang

dart
// Melelahkan jika diulang
// void daftar(void Function(String, int, bool) cb) {}

// BENAR: beri nama dengan typedef
typedef CallbackUser = void Function(String nama, int umur, bool aktif);

void daftar(CallbackUser cb) {
  cb('Budi', 17, true);
}

void main() {
  daftar((nama, umur, aktif) => print('$nama, $umur, $aktif'));
}

Kesimpulan

Higher-order function = fungsi yang memakai fungsi lain sebagai parameter atau return value. Pola ini memisahkan kerangka dari detail, menghasilkan kode reusable: callback, retry, strategi. Kuasai ini dan kamu membaca kode Flutter modern dengan lancar.

Catatan teknis: Method collection seperti .map(), .where(), .forEach() adalah higher-order function bawaan. Setiap kali memakainya, kamu sudah mempraktikkan konsep ini.

Tantangan

Filter generik

Buat higher-order function saring(List<int> data, bool Function(int) syarat) yang mengembalikan list berisi elemen yang memenuhi syarat. Uji dengan syarat genap dan syarat > 10.

text
List<int> saring(List<int> data, bool Function(int) syarat) {
  // TODO
  return [];
}

void main() {
  var angka = [5, 12, 8, 20, 3];
  // TODO: uji dengan (n) => n % 2 == 0 dan (n) => n > 10
}