لماذا لا يدعم المخطط بيئات الدرجة الأولى؟

StackOverflow https://stackoverflow.com/questions/617325

  •  03-07-2019
  •  | 
  •  

سؤال

لقد قرأت من خلال SICP (بنية وتفسير برامج الكمبيوتر) وكنت متحمسًا جدًا لاكتشاف هذا النموذج الخاص الرائع: "Make-Environment" ، والذي يثبتون استخدامه مع Eval كطريقة لكتابة رمز وحدات (مقتطف من القسم 4.3 على "الحزم"):

(define scientific-library
  (make-environment
   ...
   (define (square-root x)
    ...)))

ثم يوضحون كيف يعمل مع

((eval 'square-root scientific-library) 4)

في مثالهم ، يذهبون بعد ذلك للتظاهر بالضبط الاستخدام الذي أرغب فيه - طريقة أنيقة وأبنية للقيام بأسلوب "OO" في المخطط ... إنهم "سلبيات" معًا "نوع" ، وهو ما تم إرجاعه في الواقع بواسطة الشكل الخاص "Make -Environment" ( أي vtable) ، و arg ("الدولة") ...

كنت متحمسًا جدًا لأن هذا بالضبط ما كنت أبحث عنه كوسيلة للقيام بالإرسال متعدد الأشكال "بواسطة الرمز" في المخطط دون الحاجة إلى كتابة الكثير من التعليمات البرمجية الصريحة أو وحدات الماكرو.

أي أريد إنشاء "كائن" لديه ، على سبيل المثال ، اثنين وظائف ، التي أدعوها في سياقات مختلفة ... لكنني لا أريد الرجوع إليها بواسطة "Car" و "CDR" ، أريد كليهما يعلن و تقييم لهم بأسمائهم الرمزية.

على أي حال ، عندما قرأت هذا ، لم أستطع الانتظار للعودة إلى المنزل وتجربته.

تخيل خيبة أملي ثم عندما واجهت ما يلي في كل من مخطط PLT ومخطط Chez:

> (make-environment (define x 3))
Error: invalid context for definition (define x 3).
> (make-environment)
Error: variable make-environment is not bound.

ماذا حدث لـ "Make-Environment" كما هو مشار إليه في SICP؟ بدا كل شيء أنيقة للغاية ، وما أريد بالضبط ، ومع ذلك لا يبدو أنه مدعوم في أي مترجمين مترجمين حديثين؟

ما هو الأساس المنطقي؟ هل هو ببساطة أن "البيئة" لها اسم مختلف؟

تم العثور على مزيد من المعلومات لاحقًا

لقد نظرت إلى النسخة عبر الإنترنت:

http://mitpress.mit.edu/sicp/full-text/book/book-zh-28.html#٪_SEC_4.3

كنت أقرأ كانت الطبعة الأولى من SICP. يبدو أن الإصدار الثاني قد حل محل المناقشة على الحزم بقسم عن البرمجة غير المحددة ومشغل "AMP".

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

المحلول

بعد المزيد من الحفر حولها اكتشفت هذا موضوع مفيد على Newsnet:

"إن محددات التقييم والبيئة R5Rs هي حل وسط بين أولئك الذين يكرهون بعمق بيئات من الدرجة الأولى ويريدون إجراء تقييم مقيد ، وأولئك الذين لا يستطيعون قبول/فهم التقييم دون حجة ثانية هي بيئة."

كما وجدت هذا "العمل":

(define-syntax make-environment 
  (syntax-rules () 
    ((_ definition ...) 
     (let ((environment (scheme-report-environment 5))) 
       (eval '(begin definition 
                     ...) 
             environment) 
       environment)))) 


(define arctic 
  (make-environment 
    (define animal 'polarbaer))) 

(مأخوذ من هذه)

ومع ذلك ، انتهى بي الأمر إلى اعتماد نمط "رسالة" نوعًا ما مثل الرجل الأول الذي اقترحه - أعيد مجموعة من الوظائف ، ولدي طريقة "إرسال عام" لاستدعاء وظيفة معينة بالاسم ... أي شيء من هذا القبيل

(define multiply
  (list
    (cons 'differentiate (...))
    (cons 'evaluate (lambda (args) (apply * args)))))

(define lookup
  (lambda (name dict)
    (cdr (assoc name dict))))

; Lookup the method on the object and invoke it
(define send
  (lambda (method arg args)
    ((lookup method arg) args))

((send 'evaluate multiply) args)

لقد قرأت كذلك وأدرك أن هناك كل شيء إذا أردت حقًا تبني نمط OO بالكامل - لكنني أعتقد أن حتى أعلاه مبالغة إلى حد ما.

نصائح أخرى

المخطط لا يحتوي على بيئات من الدرجة الأولى لأسباب الأداء. عندما تم إنشاء المخطط ، لم يكن أسرع لغة حولها بسبب أشياء رائعة مثل وظائف الدرجة الأولى ، والاستمرارية ، وما إلى ذلك. إن إضافة بيئات من الدرجة الأولى كانت تشل الأداء إلى أبعد من ذلك. لذلك كانت مفاضلة تم إجراؤها في أيام المخطط المبكرة.

لقد كتبوا ذلك على هذا النحو لأن مخطط معهد ماساتشوستس للتكنولوجيا ، في الواقع ، لديهم بيئات من الدرجة الأولى ، ويفترض أن هذا ما يخطط للكتاب لتدريس فصلهم (منذ أن كتب الكتاب في معهد ماساتشوستس للتكنولوجيا).

الدفع http://groups.csail.mit.edu/mac/projects/scheme/

ومع ذلك ، فقد لاحظت أن مخطط معهد ماساتشوستس للتكنولوجيا ، على الرغم من أنه لا يزال يتم تطويره بنشاط إلى حد ما ، يفتقر إلى العديد من الميزات التي سيكون لها مخطط حديث حقًا ، مثل واجهة الوظيفة الأجنبية أو دعم واجهة المستخدم الرسومية. ربما لن ترغب في استخدامه لمشروع تطوير برمجيات جاد ، على الأقل ليس بنفسه.

هل يعمل المرسل الكلاسيكي؟ أعتقد أن هذا مشابه لما تبحث عنه.

(define (scientific-library f)
  (define (scientific-square-root x) (some-scientific-square-root x))
  (cond ((eq? f 'square-root) scientific-square-root)
        (else (error "no such function" f))))
(define (fast-library f)
  (define (fast-square-root x) (some-fast-square-root x))
  (cond ((eq? f 'square-root) fast-square-root)
        (else (error "no such function" f))))

((scientific-library 'square-root) 23)
((fast-library 'square-root) 23)

يمكنك حتى الجمع بين مثال المكتبات العلمية والسريعة في طريقة إرسال كبيرة واحدة:

(define (library l f)
  (define (scientific-library f)
    ...)
  (define (fast-library f)
    ...)
  (cond ((eq? l 'scientific) (scientific-library f))
        ((eq? l 'fast) (fast-library f))
        (else (error "no such library" l))))
(library 'fast 'square-root)
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top