См. Также мой ответ на , как работает головоломка Инь-Ян , на которую мне нужно было найти ответ, прежде чем я смог ответить на него.
Бытие«типизированный» язык сам по себе не имеет значения, является ли эта головоломка выразимой в нем (независимо от того, насколько расплывчат термин «типизированный язык»).Тем не менее, ответить на ваш вопрос наиболее буквально: да, это возможно, потому что сама Схема является типизированным языком: каждое значение имеет известный тип.Это явно не то, что вы имели в виду, поэтому я предполагаю, что вы имеете в виду, возможно ли это в языке, где каждой переменной присваивается постоянный тип, который никогда не изменяется (он же «статически типизированный язык»).
Более того, я 'Предположим, что вы хотите, чтобы дух головоломки сохранялся при выражении на каком-либо языке.Очевидно, что можно написать интерпретатор Scheme в машинном коде x86, и, очевидно, можно написать интерпретатор машинного кода x86 на языке typed , который имеет только целочисленные типы данных и указатели на функции.Но результат не в том же «духе».Поэтому, чтобы сделать это более точным, я наложу дополнительное требование: результат должен быть выражен с использованием истинных продолжений.Не эмуляция, а реальные полные продолжения.
Итак, вы можете иметь статически типизированный язык с продолжениями?Оказывается, вы можете, но вы все равно можете назвать это обманом.Например, в C #, если мои продолжения были определены как «функция, которая принимает объект и возвращает объект», где «объект» - это тип, который может содержать что угодно, сочтете ли вы это приемлемым?Что если функция принимает и возвращает «динамический»?Что если у меня есть «типизированный» язык, где каждая функция имеет один и тот же статический тип: «функция», без определения типов аргументов и возвращаемых типов?Является ли результирующая программа в том же духе, даже если она использует истинные продолжения?
Моя точка зрения заключается в том, что свойство «статически типизированный» по-прежнему допускает огромное количество изменений в системе типов, достаточное для того, чтобы всеразличия.Так что просто для удовольствия, давайте рассмотрим, что система типов должна поддерживать, чтобы квалифицировать ее как нечестную по любой мере.
Оператор call/cc(x)
также может быть записан как x(get/cc)
, что значительнолегче понять на мой взгляд.Здесь x
- это функция, которая принимает Continuation и возвращает значение, а get/cc
возвращает Continuation
.Continuation
имеет все черты функции;он может быть вызван с одним аргументом и будет заменять значение, переданное туда, где изначально находился get / cc, который его создал, дополнительно возобновляя выполнение в этой точке.
Это означает, что get / cc имеетНеловкий тип: это function
, но то же самое местоположение в конечном итоге вернет значение, тип которого мы еще не знаемПредположим, однако, что в духе статически типизированных языков мы требуем, чтобы возвращаемый тип был фиксированным.То есть, когда вы вызываете объект продолжения, вы можете передавать только значения предопределенного типа.При таком подходе тип функции продолжения может быть определен с помощью рекурсивного выражения вида T = function T->T
.Как указал друг, этот тип может быть фактически объявлен в C #: public delegate T T(T t);
!
Так что у вас есть;«печатание» не исключает и не гарантирует, что вы можете выразить эту головоломку, не изменяя ее природу.Однако, если вы разрешите статический тип «может быть чем угодно» (известный как object
в Java и C #), то единственное, что вам нужно, - это поддержка истинных продолжений, и головоломка может быть представлена без проблем.
Подходя к тому же вопросу с другой точки зрения, подумайте о том, чтобы переписать головоломку в нечто более напоминающее традиционный императивный язык со статической типизацией, который я объяснил в связанном ответе :
yin = (function(arg) { print @; return arg; })(get-cc);
yang = (function(arg) { print *; return arg; })(get-cc);
yin(yang);
Здесь тип yin
и yang
никогда не меняется .Они всегда хранят "продолжение C, которое принимает C и возвращает C" .Это очень совместимо со статической типизацией, единственное требование которой состоит в том, чтобы тип не изменялся при следующем выполнении этого кода.