Мне было трудно понять, в чем заключается этот принцип и почему он так важен для языкового дизайна.
По сути, в нем говорится, что для каждого выражения expr
в языке должно быть точно так же, как эта конструкция:
(function () { return expr; })()
Кроме того, я слышал, что Ruby подчиняется этому принципу, а Python - нет. Я не понимаю, почему это так, или если это вообще так.
design
language-agnostic
Эндрю
источник
источник
expr
получает текущую трассировку стека.Ответы:
Я никогда раньше не слышал о «Принципе соответствия Теннента» и тем более о его важности для языкового дизайна. Погугление выражений, похоже, ведет к одному блогу Нила Гафтера 2006 года, в котором изложено, что он думает, и как, по его мнению, это должно относиться и к замыканиям. И большинство всех остальных на форумах, кажется, ссылаются на запись Gafter.
Вот, однако, упоминание упомянутого «TCP» Дугласом Крокфордом (имя, которое я знаю и которому доверяю): http://java.sys-con.com/node/793338/ . Частично
Поэтому кажется, что название «Принцип соответствия Теннента» используется неправильно, и все, о чем Нил говорит, возможно, следует называть «Воображаемым и, возможно, обобщенным ПТС» Гафтера ... или что-то подобное. В любом случае недостаточно спрятаться за распечатанным занавесом книги
источник
Я рассматриваю это как часть общего правила, согласно которому хорошо разработанный язык делает то, что программист, естественно, ожидает. Если у меня есть блок кода, который я хочу преобразовать в замыкание, и я обертываю этот блок подходящим синтаксисом, не задумываясь об отдельных строках кода, то я ожидаю, что этот блок будет выполнять то же самое в замыкании, что и он. сделал встроенный. Если некоторые операторы используют ключевое слово «this» (возможно, неявно) и язык заставляет «this», используемый внутри замыкания, ссылаться на анонимный класс, используемый для его представления, а не на класс, который определяет метод, определяющий замыкание, тогда значение эти утверждения изменились, мой блок кода больше не делает то, что я думаю, и мне нужно отследить ошибку и выяснить, как изменить мой код, чтобы он работал в замыкании.
Эту проблему можно также устранить с помощью интегрированной среды разработки с интеллектуальными инструментами рефакторинга, которые могут извлекать замыкания, обнаруживать потенциальные проблемы и даже автоматически корректировать извлеченный код для решения проблем.
источник
Клаус Рейнке: касательно «Языкового дизайна, основанного на семантических принципах»
Теннента Дает интересную интерпретацию принципов:
«Соответствие - это принцип, который позволяет нам сказать, что
а также
должно быть эквивалентным, и что все, что мы можем делать в списках формальных параметров, мы также должны иметь возможность делать в объявлениях и наоборот. "[см. также Reinke, ниже.]
Р.Д. Теннент: Методы проектирования языка, основанные на семантических принципах
"Два метода проектирования языка, основанные на принципах, полученных на основе денотационного подхода к семантике языка программирования, описаны и проиллюстрированы приложением к языку Pascal. Принципами, во-первых, является соответствие между параметрическим и декларативные механизмы, и, во-вторых, принцип абстракции для языков программирования, адаптированных из теории множеств. Несколько полезных расширений и обобщений Паскаля появляются благодаря применению этих принципов, включая решение проблемы параметров массива и средство модульности ».
Клаус Рейнке: «О функциональном программировании, проектировании языков и постоянстве» на Haskell
источник
Чтобы ответить на вопрос, почему CP Теннента так важен для языкового дизайна, я хотел бы процитировать Нила Гафтера :
Любое нарушение TCP может повредить программисту в будущем, когда он ожидает, что замыкания будут работать как код без замыканий, но обнаружит, что в случае нарушения TCP они этого не делают.
источник
RE Python не следует этому принципу. Как правило, он следует принципу. Основной пример:
Тем не менее, Python определяет выражения и операторы отдельно. Поскольку
if
ветви,while
циклы, деструктивное присваивание и другие операторы вообще не могут использоваться вlambda
выражениях, буква принципа Теннента к ним не относится. Тем не менее, ограничиваясь использованием только выражений Python, все равно получается полная система Тьюринга. Поэтому я не считаю это нарушением принципа; или, скорее, если это нарушает принцип, то никакой язык, который определяет утверждения и выражения отдельно, не может соответствовать этому принципу.Кроме того, если тело
lambda
выражения захватывает трассировку стека или выполняет другой самоанализ в виртуальной машине, это может вызвать различия. Но, на мой взгляд, это не должно рассматриваться как нарушение. Еслиexpr
и(lambda: expr)()
обязательно компилировать в один и тот же байт-код, то этот принцип действительно касается компиляторов, а не семантики; но если они могут компилироваться в другой байт-код, мы не должны ожидать, что состояние VM будет одинаковым в каждом случае.При использовании синтаксиса понимания может возникнуть неожиданность, хотя я считаю, что это также не является нарушением принципа Теннента. Пример:
Сюрприз - результат того, как определены списочные представления. Вышеупомянутое «неожиданное» понимание эквивалентно следующему коду:
При таком понимании «неожиданное» понимание выше не так удивительно и не является нарушением принципа Теннента.
источник