Лямбда-функції

Лямбда-функції у Scheme — анонімні функції без імені. Вони визначаються вбудовано і зазвичай використовуються для коротких одноразових операцій. Конструкція lambda — потужний інструмент функціонального програмування для стислої й гнучкої логіки.

Лямбда-функції особливо корисні, коли:

  • потрібна невелика функція для конкретної тимчасової мети;
  • функції передаються як аргументи функціям вищого порядку, наприклад map, filter або fold;
  • функції повертаються з інших функцій.

Синтаксис лямбда-функцій

Лямбда-функцію можна визначити окремо…

(lambda (parameter1 parameter2 ...)
  body-expression)

…або одразу викликати:

((lambda (parameter1 parameter2 ...)
   body-expression)
 argument1 argument2 ...)
  • parameter1, parameter2, ...: параметри функції.
  • body-expression: логіка, яка виконується під час виклику.
  • Негайний виклик: друга форма одразу викликає лямбду з аргументами.

Приклади лямбда-функцій

Прості обчислення

((lambda (x y) (+ x y)) 3 5)  ; Повертає 8
  • Створюється лямбда-функція для додавання двох чисел (x і y).
  • Функція одразу викликається з аргументами 3 і 5.

Вбудовані лямбда-функції

Наступний приклад показує for-each з іменованою функцією та з лямбда-функцією:

Іменована функція:

(define (print-item x)
  (lumi-message (number->string x)))

(for-each print-item (list 1 2 3 4))
  • Пояснення:
    • print-item перетворює число на рядок (number->string) і виводить його через lumi-message.
    • for-each застосовує print-item до кожного елемента списку (1 2 3 4).

Вихід: 1 2 3 4

Лямбда-функція:

Ту саму логіку можна записати вбудовано, без окремої іменованої функції:

(for-each (lambda (x) (lumi-message (number->string x)))
  (list 1 2 3 4))
  • Пояснення:
    • (lambda (x) (lumi-message (number->string x))) визначає анонімну функцію.
    • for-each застосовує її до кожного елемента списку (1 2 3 4).

Вихід: 1 2 3 4

Лямбда-функції як аргументи

Лямбда-функції часто передають безпосередньо до функцій вищого порядку, наприклад map або filter.

Зведення списку чисел у квадрат

(map (lambda (x) (* x x)) '(1 2 3 4))  ; Повертає (1 4 9 16)
  • Лямбда зводить у квадрат кожен елемент списку.
  • map застосовує лямбду до кожного елемента.

Лямбда-функції як значення, що повертаються

Лямбда-функцію можна повернути з іншої функції для динамічної поведінки.

Створення функції-додавання

(define (make-adder n)
  (lambda (x) (+ x n)))

(define add5 (make-adder 5))
(add5 10)  ; Повертає 15
  • make-adder генерує лямбда-функцію, яка додає число n.
  • Повернена лямбда зберігається в add5 і додає 5 до вхідного значення.

Лямбда з let

Лямбди часто використовують з let для локальних тимчасових функцій.

Локальна лямбда для додавання

(let ((add (lambda (a b) (+ a b))))
  (add 3 4))  ; Повертає 7
  • let прив’язує лямбда-функцію до імені add.
  • Лямбда використовується як звичайна функція в межах let.

Лямбди з функціями вищого порядку

Лямбди особливо корисні в поєднанні з функціями вищого порядку для складних перетворень даних.

Фільтрування парних чисел

(filter (lambda (x) (= (modulo x 2) 0)) '(1 2 3 4 5 6))  ; Повертає (2 4 6)
  • Лямбда перевіряє, чи число парне.
  • filter зберігає лише парні числа зі списку.

Переваги лямбда-функцій

  • Стислість: зменшують шаблонний код, усуваючи потребу в окремих іменованих функціях.
  • Гнучкість: їх можна визначати та використовувати там, де потрібно.
  • Читабельність: для коротких завдань лямбди роблять намір зрозумілим без зайвих іменованих функцій.

Коли використовувати лямбда-функції

Використовуйте лямбда-функції, коли:

  • логіка коротка і самодостатня;
  • функція потрібна лише тимчасово або в певній області;
  • ви працюєте з функціями вищого порядку, наприклад map, filter або reduce.

Уникайте лямбд для складної багаторядкової логіки — це погіршує читабельність. Для розширених операцій краще іменована функція.

Підсумок

Лямбда-функції в Scheme дають стислий і потужний спосіб визначати анонімні функції для конкретних завдань. Розуміння lambda допоможе писати чистіші, модульніші та ефективніші скрипти.