سؤال

أواجه بعض المتاعب في فهم سلوك برنامج المخطط التالي:

(define c
  (dynamic-wind
    (lambda () (display 'IN)(newline))
    (lambda () (call/cc (lambda (k)
                     (display 'X)(newline)
                     k)))
    (lambda () (display 'OUT)(newline))))

كما أفهم ، سوف يكون C ملزماً بالاستمرار الذي تم إنشاؤه قبل "(عرض" X) ".

ولكن يبدو أن استخدام C لتعديل نفسه! تعريف المطبوعات أعلاه (كما كنت أتوقع) في ، x والخروج:

IN
X
OUT

وهو إجراء:

#;2> c
#<procedure (a9869 . results1678)>

الآن ، أتوقع أنه عندما يتم استدعاؤه مرة أخرى ، سيتم طباعة X ، وليس كذلك!

#;3> (c)
IN
OUT

والآن لم يعد C إجراءً ، ولن يعمل الاستدعاء الثاني لـ C!

#;4> c    ;; the REPL doesn't answer this, so there are no values returned
#;5> (c)

Error: call of non-procedure: #<unspecified>

        Call history:

        <syntax>            (c)
        <eval>              (c)    <--

كنت أتوقع أن يفعل كل استدعاء إلى (ج) نفس الشيء - الطباعة في ، x ، والخروج. ماذا ينقصني؟

هل كانت مفيدة؟

المحلول

إن تشغيل هذا في المضرب أكثر فائدة قليلاً:

-> (define c
     (dynamic-wind
       (lambda () (display 'IN)(newline))
       (lambda () (call/cc (lambda (k)
                             (display 'X)(newline)
                             k)))
       (lambda () (display 'OUT)(newline))))
IN
X
OUT
-> c
#<continuation>
-> (c)
IN
OUT
define-values: context (defining "c") expected 1 value, received 0 values
-> (c 99)
IN
OUT
-> c
99

لاحظ على وجه التحديد c يلتزم بقيمة استمرار - لأن تعبيرك يعود k كقيمة. و k بحد ذاته هو استمرار تعبير القيمة ، مما يعني أن هذا الاستمرار هو الذي ينتظر الحصول على قيمة للازم c. لذا فإن التذرع بأنه يتطلب قيمة واحدة ، كما يتطلب المضرب ، مما يساعد على توضيح ما يحدث هنا (يبدو أن مخطط MIT يعامله بصمت على أنه غير محدد). على أي حال ، فإن تطبيق هذا الاستمرار على 99 يعني أن قيمة الإرجاع من هذا التعبير هي 99 - لذلك يمكنك العودة إلى السياق (الطباعة IN) وإعادة 99 يكون مرتبطا ب c, وطباعة OUT في طريقك للخروج. لقد قمت الآن بتعديل c للحصول على 99 بدلاً من ذلك ، لذلك لا يمكنك تسميتها للمرة الثالثة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top