Якщо вже мова зайшла за Clojure та його нащадків, поговорімо про таку корисну річ, як «->>» — макрос для розгортання вкладених виразів.
Для чого це взагалі потрібно? Працюючи з серією вкладених викликів спискових/ітераторних функцій (таких як map, filter, reduce та ін.), ми неминуче зіткнемося з характерною ліспівською батареєю дужок наприкінці виразу. І хоча сучасні редактори та середовища розробки дозволяють швидко знайти парну дужку, читати такі вирази очима доволі незручно, та й ризик помилки зростає. І якщо в Common Lisp чи Scheme з цим якось миряться (бо як же інакше?), а в Python просто міняють функціональний стиль на процедурний, то в Clojure можна цього уникнути:
(->> lst
(map f1)
(filter f2)
(map f3)
(map f4)
(reduce f5)
)
що після обробки макросів трансформується в
(reduce f5 (map f4 (map f3 (filter f2 (map f1 lst)))))
тобто, кожен вираз зі списку підставляється в наступний вираз останнім аргументом.
Тепер повернімось до пітона. В принципі, зовсім необов'язково пакувати все в один вираз — його можна переписати як серію присвоєнь:
x=lst
x=map(f1, x)
x=filter(f2, x)
x=map(f3, x)
x=map(f4, x)
x=reduce(f5, x)
Хоча любителям функціонального стилю може сподобатися така функція:
def rarg(x):
return lambda *args, **kwargs:\
rarg(args[0](*args[1:]+(x,), **kwargs)) if args else x
Маючи її, наведений вище приклад можна переписати так:
(rarg(lst)
(map, f1)
(filter, f2)
(map, f3)
(map, f4)
(reduce, f5)
())
Або більш зручний для демонстрації приклад:
>>> rarg('qwertyuiop')(filter, lambda c:c>'q')(map, repr)(', '.join)()
"'w', 'r', 't', 'y', 'u'"