Привет, Хабр!
В этой статье я хотел бы рассказать о том, что пришло в Python из функциональных языков программирования. Заинтересовавшихся прошу под кат.
Генераторы списков
Это легко и просто: вместо
l = []
for x in range(10):
if x % 2 == 0:
l.append(x)
мы пишем
l = [x for x in range(10) if x % 2 == 0]
Коротко и понятно.
В Haskell тоже самое буде выглядеть так:
let l = [x | x <- [0..10], x `mod` 2 == 0]
Лямбды
Допустим, мы пишем графический интерфейс и у нас есть функция button(**kwargs), где допустимые именованные аргументы: text — для текста, width — для ширины, height — для высоты и command — для callback-функции:
def callback(event):
print("Button pressed")
button(text="Press me", width=32, height=16, command=callback)
Обратите внимание, насколько маленький у нас callback, неужели его нелзя пропихнуть аргументом? Можно! Нам помогут лямбды:
button(text="Press me", width=32, height=16, command=lambda x: print("Button pressed"))
Чисто и легко!
В Haskell передача функции в качестве аргумента встречается на каждом шагу, например функция map берет функцию и список и возвращает список, к каждому элементу которого была применена эта функция:
map (\x -> x+1) [1..10]
На Python это:
map(lambda x: x+1, [x for x in range(1, 10)])
Правда, в Python нет map.
upd: map есть!
Карринг
Карринг (каррирование) — это когда мы передаем старой функции один или несколько аргументов, чтобы получить новую, которая принимает остальные (спасибо AnutaU за более точное определение). Например: print — это функция (я использую Python 3), у нее есть именованный аргумент end — конец строки, по умолчанию он равен "\n". Я хочу не переходить на новую строку, тогда пишу
print(str, end="")
Давайте сделаем функцию printf, которая не будет переходить на новую строку
def printf(*args, **kwargs):
kwargs["end"] = ""
print(*args, **kwargs)
Коряво, можно и проще:
from functools import partial
printf = partial(print, end = "")
Вот он, карринг — мы говорим, что хотим точно такой же, но с перламутровыми пуговицами функцию print, но чтобы end был равен "". Все просто.
И снова Haskell: у нас есть функция +, которая берет два аргумента, мы говорим:
let plusTwo = (+2)
теперь у меня есть функция, которая прибавляет 2 к единственному аргументу.
У меня все, если вы знаете, что еще есть в Python из функциональщины — прошу в комментарии.
Вопросы и отзывы туда же.