Вероятно, самый легкий путь к Win32 API.e.g PInvoke LogonUser.
Ссылка MSDN здесь...
Определенно хочет использовать тип
LOGON32_LOGON_NETWORK (3)
входа в систему, Это создает легкий маркер только - идеально подходящий для проверок AuthN. (другие типы могут использоваться для создания интерактивных сессий и т.д.)
В отличие от обычного сетевого этикета SO, я отвечаю на свой вопрос, но больше как редактор, чем поставщик ответа.
Через некоторое время я задал похожий вопрос на LtU . В конце концов, это те ребята, которые целый день размышляют о языковом дизайне, не так ли, и один из ответов наконец-то пришелся мне по душе. Теперь вещи, упомянутые здесь, например, Эли или в исходном вопросе, имеют для меня гораздо больше смысла. Все дело в том, что включается в продолжение и где применяется продолжение.
На одном из плакатов в LtU написано:
Это было бы менее универсально. Если вы хотите такого поведения, вы можете просто сделать:
(call/cc (lambda (x) x))
Вы можете взглянуть на примеры использования продолжений в «Даррелл Фергюсон и Дуайт Деуго.« Звонок с текущими шаблонами продолжения ». 8-я конференция по шаблонным языкам программ. Сентябрь. 2001. " ( http://library.readscheme.org/page6.html ) и попробуйте переписать их, используя call / cc-return, как указано выше.
Если вы используете такую конструкцию, как показывает Джей, вы можете получить продолжение, но в некотором смысле полученное значение уже испорчены, потому что вы уже в этом продолжении. Напротив, call / cc
может использоваться для захвата продолжения, которое все еще ожидает выполнения вне текущего выражения. Например, одно из самых простых применений продолжений - реализовать своего рода прерывание
:
(call/cc (lambda (abort)
(+ 1 2 (abort 9))))
Вы не можете сделать это с помощью описываемой вами операции. Если вы попробуете:
(define (get-cc) (call/cc values))
(let ([abort (get-cc)]) (+ 1 2 (abort 9)))
, то получите ошибку о применении 9
в качестве процедуры. Это происходит потому, что abort
переходит обратно к let
с новым значением 9
- что означает, что вы ' Теперь мы делаем второй раунд того же выражения сложения, за исключением того, что теперь abort
привязан к 9
...
Два дополнительных связанных примечания:
call / cc
- это немного сложный, поскольку он принимает на себя функцию - концептуально более простая в использовании конструкция let / cc
, который вы можете найти в некоторых реализациях, таких как PLT Scheme. Приведенный выше пример становится (let / cc abort (+ 1 2 (abort 9)))
. Я предлагаю начать с вопроса: что значит быть первоклассным продолжением?
Продолжение выражения по существу состоит из двух частей: во-первых, замыкание ( т.е. окружение) этого выражения; и во-вторых, представление того, что следует делать с результатом выражения. Таким образом, язык с первоклассными продолжениями - это язык, который имеет структуры данных, инкапсулирующие эти части, и который обрабатывает эти структуры данных так же, как и любые другие.
call / cc - особенно элегантный способ реализовать эту идею: текущее продолжение упаковано в виде процедуры, которая инкапсулирует то, что должно быть сделано с выражением, как то, что процедура делает при применении к выражению; представление продолжения таким образом просто означает, что закрытие этой процедуры содержит среду в том месте, где она была вызвана.
Вы можете представить себе реализацию идеи первоклассных продолжений другими способами. Они не были бы call / cc, и мне трудно представить, как такое представление может быть проще.
На прощание, рассмотрим реализацию let / cc, упомянутую Эли, которую я предпочитаю называть bind / cc:
(define-syntax bind/cc
(syntax-rules ()
((bind/cc var . body)
(call/cc (lambda (var) . body)))))
И в качестве упражнения, как бы вы реализовали call / cc на основе bind / cc?