RE Python не дотримується цього принципу. Як правило, він дотримується принципу. Основний приклад:
>>> x = ['foo']
>>> x
['foo']
>>> x = (lambda: ['foo'])()
>>> x
['foo']
Однак Python визначає вирази та оператори окремо. Оскільки if
гілки, while
петлі, деструктивне призначення та інші висловлювання взагалі не можуть бути використані у lambda
виразах, буква принципу Теннента не стосується їх. Тим не менш, обмеження себе використовувати лише вирази Python все ще створює повну систему Тьюрінга. Тож я не вважаю це порушенням принципу; точніше, якщо це порушує принцип, то жодна мова, яка окремо визначає висловлювання та вирази, не може відповідати цьому принципу.
Крім того, якщо тіло lambda
виразу фіксувало слід стека або робило інший самоаналіз у ВМ, це може спричинити відмінності. Але, на мою думку, це не слід вважати порушенням. Якщо expr
і (lambda: expr)()
обов'язково компілювати в один і той же байт-код, то принцип дійсно стосується компіляторів, а не семантики; але якщо вони можуть компілювати різні байт-коди, ми не повинні очікувати, що стан VM буде однаковим у кожному випадку.
Сюрприз можна зустріти, використовуючи синтаксис розуміння, хоча я вважаю, що це також не є порушенням принципу Теннента. Приклад:
>>> [x for x in xrange(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [f() for f in [lambda: x for x in xrange(10)]] # surprise!
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
>>> # application of Tennent principle to first expression
... [(lambda: x)() for x in xrange(10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> [f() for f in [(lambda x: lambda: x)(x) for x in xrange(10)]] # force-rebind x
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> map(lambda f:f(), map(lambda x: lambda: x, xrange(10))) # no issue with this form
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Несподіванка - це результат того, як визначено розуміння списку. Наведене вище розуміння "сюрприз" еквівалентно цьому коду:
>>> result = []
>>> for x in xrange(10):
... # the same, mutable, variable x is used each time
... result.append(lambda: x)
...
>>> r2 = []
>>> for f in result:
... r2.append(f())
...
>>> r2
[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
Побачене таким чином, розуміння "сюрпризу" вище є менш дивним, а не порушенням принципу Теннента.