Домашнее задание № 9

Вопрос 1: Списковые включения

Вспомни, как облегчают жизнь в Python списковые включения (list comprehensions). Они позволяют создавать списки из итерируемых значений.

[<отображающее выражение> for <имя> in <итерируемое выражение> if <фильтрующее выражение>]

Используя макросы, создай списковые включения для Scheme, которые создают списки из списков. В частности сделай так, чтобы макрос list-of мог вызываться так:

(list-of <отображающее выражение> for <имя> in <список> if <фильтрующее выражение>)

Вызов list-of должен возвращать новый список, полученный из элементов <list>, каждый из которых обрабатывается так:

  • связать имя <name> с элементом;

  • если <фильтрующее выражение> возвратит истинное значение, то вычислить <отображающее выражение> и добавить результат в новый список.

Некоторые примеры:

scm> (list-of (* x x) for x in '(3 4 5) if (odd? x))
(9 25)
scm> (list-of 'hi for x in '(1 2 3 4 5 6) if (= (modulo x 3) 0))
(hi hi)
scm> (list-of (car e) for e in '((10) 11 (12) 13 (14 15)) if (list? e))
(10 12 14)

Ты можешь использовать встроенные процедуры map и filter.

Также может пригодиться макрос for, рассмотренный в соответствующей лекции.

(define-macro (list-of map-expr for var in lst if filter-expr)
  nil ;ТВОЙ КОД ЗДЕСЬ
)

Вопрос 2

Припомни, что в списковых включениях Python часть с условием была опциональной. Постарайся изменить свой макрос list-of так, чтобы списковые включения Scheme не требовали наличия условия.

Особая форма define-macro может принимать произвольное количество параметров, более того, их можно не перечислять по именам. После обязательных параметров можно добавить . <символ>. Это будет означать, что все неименованные параметры будут переданы в макрос списком, связанным с именем <символ>.