Python и Smalltalk - Сравнение возможностей метапрограммирования - PullRequest
10 голосов
/ 28 июля 2011

В последнее время я изучаю Python и поражаюсь его превосходным возможностям метапрограммирования во время выполнения.Ранее я сталкивался с термином «метапрограммирование во время выполнения», когда читал о Smalltalk, который, насколько я знаю, может похвастаться лучшими возможностями метапрограммирования во время выполнения.Насколько хорошо Python сочетается с Smalltalk по сравнению с метапрограммированием?В чем заметные различия между подходами двух языков?

Ответы [ 2 ]

12 голосов
/ 28 июля 2011

Python действительно неплохо держится здесь. Smalltalk обычно не делает явного различия между программой и метапрограммой, но Python является более явным - например, специальный синтаксис для декораторов или __foo__() соглашение об именах для ловушек метапрограммирования. Это хорошая вещь.

С другой стороны, это что-то вроде сравнения яблок с апельсинами. Smalltalk - это более компактный и компактный язык, чем Python, и поэтому для управления метапрограммами требуется меньше материалов. Например, рассмотрим __getattr__(). Это ловушка, которая позволяет объектам Python предоставлять настраиваемую реализацию доступа к атрибутам. У Smalltalk ничего подобного нет. Но! Smalltalk обеспечивает более плотную инкапсуляцию внутреннего состояния объекта, и нет эквивалента синтаксиса object.attribute, используемого в Python. Таким образом, чтение состояния объекта требует прохождения метода ... который именно то, что обеспечивает __getattr__(). Поэтому во многих случаях, когда вы используете __getattr__() в Python, вы просто пишете обычный метод в Smalltalk - метапрограммирование не требуется.

И это везде так: Python __getitem__() и друзья позволяют писать классы, которые имитируют списки или словари. Smalltalk не нуждается в этом, потому что Array и Dictionary - это просто обычные классы Smalltalk, и нет специального синтаксиса для их использования. Python __eq__() и т. Д. Включают перегрузку операторов. Smalltalk не имеет операторов, поэтому вы можете реализовать +, не делая ничего особенного. Contextlib Python предоставляет некоторые изящные инструменты для реализации ваших собственных менеджеров контекста. Smalltalk не имеет конструкции with, но у него действительно упрощенный синтаксис для лямбда-выражений, который позволяет делать то же самое простым способом.

Возможности метапрограммирования в Smalltalk, как правило, довольно низкоуровневые. Вы можете, например, создать свои собственные CompiledMethod экземпляры и вставить их в словарь методов класса. Вы также можете написать свой собственный компилятор и указать, что все методы определенного класса будут компилироваться с ним. Это позволяет делать все что угодно - я видел проекты, которые экспериментируют с альтернативными синтаксисами, инструментальный байт-код для профилирования, прерывания чтения и записи в переменные экземпляра для прозрачного сохранения и так далее.

Средства метапрограммирования Smalltalk являются мощными, но они не так аккуратно организованы, как Python, и не используются так часто.

10 голосов
/ 28 июля 2011

Опубликовано как ответ на вопрос спрашивающего.

Одна из главных идей Smalltalk - это ортогональность. Откровенно говоря Python страдает в этом отношении. Не все работает на все. Примеры:

  • inspect.getargspec() не работает со встроенными функциями или результатами вызовов functools.partial (в любом случае в интерпретаторе C).
  • eval работает только для строк выражений, а exec работает только для строк операторов.
  • Лямбда-выражения не могут быть засечены.
  • myclass = type('x', (object,), {'__init__': partial(foo, value)}) создает класс, который не может быть создан, тогда как передача эквивалентного lambda выражения вместо partial работает нормально. (Хотя это может быть просто ошибка, а не функция.)

Может быть, у PyPy нет этих проблем, я не уверен. Но я очень люблю Python и считаю очень удобным использовать метаклассы, карри и случайные дескрипторы в реальных приложениях.

...