Wednesday, May 13, 2009

О замыканиях в Python и С++

Предыдущий пост вызвал множество споров в pythonua@c.j.r на тему сложности синтаксиса С++ и сложности синтаксиса лямбд в частности. Действительно, в С++ 0x лямбды - это не one-line expressions, а полноценные анонимные функции. Именно поэтому синтаксис и так сложен.
Например, возьмём Python и его лямбды. Так как синтаксис Python изначально минималистичен, то и лямбды в нём выглядят аккуратно и понятно. Однако, с другой стороны такая минималистичность может сыграть и злую шутку. Вот пример - не так давно поднимался вопрос о замыканиях в Python. Речь в этой статье шла о таком небольшом сниппете:

l = []
for i in range(2):
for j in range(2):
l.append(lambda: i + j)
При такой реализации замыкания не происходит - в l мы получим абсолютно одинаковые функции. Основной вывод вышеприведенной статьи - правильная реализация замыканий в Python - это:
def lsum(n, m):
return lambda: n + m

l = []
for i in range(2):
for j in range(2):
l.append(lsum(i, j))
Но что мы видим в этом коде? Вместо удобного inline использования - отдельная функция, которая отвлекает внимание и всё портит.
Теперь вернёмся к С++ и посмотрим как в игру вступает один из синтаксических наворотов - capture list:
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/function.hpp>

int main()
{
std::vector<boost::function <int()>> l;
for (int i=0;i<2;++i)
for (int j=0;j<2;++j)
l.push_back([i,j]{ return i + j; });
for_each(l.begin(),
l.end(),
[](boost::function <int()> f){ std::cout << f() << "\n"; });
}
Данная программа выводит:
0
1
1
2
Как и ожидалось. Таким образом, "синтаксический мусор" в С++ 0x - это по большей части нужные и полезные вещи. Спасибо за внимание!

7 comments:

  1. Не понимаю. Почему в питоне так?

    ReplyDelete
  2. >Не понимаю. Почему в питоне так?
    Вот так сработает:
    l.append(lambda n=i, m=j: n + m)

    теперь понятно почему в Питоне именно так?

    ReplyDelete
  3. @Анонимный
    Вопрос автору статьи про Python :) Вообще, думаю, что на Python это не единственный способ (каламбур, однако :) )

    ReplyDelete
  4. Вначале не обратил внимания на статью про Python.

    Теперь, вроде понятно.

    ReplyDelete
  5. Даже с отдельной функцией питонокод не выглядит как говно^W^W так ужасно, как код на сях.

    ReplyDelete
  6. @дпвиз
    Слишком толсто троллите

    ReplyDelete
  7. @Sergey Kishchenko
    в самый раз:)

    ReplyDelete