يمكن للشخص أن يساعد في شرح هذا الإجراء المخطط

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

  •  03-07-2019
  •  | 
  •  

سؤال

سؤال:

((lambda (x y) (x y)) (lambda (x) (* x x)) (* 3 3))

كان هذا رقم 1 في منتصف الفصل الدراسي، وضعت "81 9" واعتقد أنني نسيت شطب واحد، لذلك قمت بشطب 81، وكان مذهولًا.على أية حال، أنا لا أفهم لماذا هو 81.

انا افهم لماذا (lambda (x) (* x x)) (* 3 3) = 81, ، لكن لامدا الأولى لا أفهم ما هي قيم x و y الموجودة، وما هي [body] (x y) يفعل.

لذلك كنت آمل أن يشرح لي أحد لماذا لا يبدو أن الجزء الأول يفعل أي شيء.

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

المحلول

هذا يحتاج إلى بعض المسافة البادئة للتوضيح

((lambda (x y) (x y))
 (lambda (x) (* x x))
 (* 3 3))
  • (lambda (x y) (x y)); ؛ مكالمة x مع y كمعلمة فقط.
  • (lambda (x) (* x x)); ؛ تقييم إلى مربع المعلمة.
  • (* 3 3); ؛ تقييم إلى 9

لذا فإن الأمر برمته يعني: "استدعاء وظيفة المربع مع المعلمة 9".

تحرير: يمكن كتابة نفس الشيء باسم

((lambda (x) (* x x))
 (* 3 3))

أعتقد أن نية التمرين هي تسليط الضوء على كيفية تنفيذ تقييم نموذج المخطط لتطبيق وظيفة ضمني.

نصائح أخرى

دعونا ننظر إلى هذا مرة أخرى..

((lambda (x y) (x y)) (lambda (x) (* x x)) (* 3 3))

لتقييم النموذج نقوم بتقييم كل جزء منه على حدة.لدينا ثلاثة عناصر في شكلنا.هذا في الموضع (الوظيفة) الأول:

(lambda (x y) (x y))

هذا هو العنصر الثاني للنموذج والوسيطة الأولى للوظيفة:

(lambda (x) (* x x))

العنصر الأخير في النموذج، وهو الوسيطة الثانية للدالة.

(* 3 3)

ترتيب التقييم لا يهم في هذه الحالة، لذلك دعونا نبدأ من اليسار.

(lambda (x y) (x y))

تقوم Lambda بإنشاء دالة، لذلك يتم تقييمها إلى دالة تأخذ وسيطتين، x وy، ثم تطبق x على y (بمعنى آخر، تستدعي x ​​بوسيطة واحدة y).دعونا نسمي هذا نداء-1.

(lambda (x) (* x x))

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

(* 3 3)

ومن الواضح أن هذا يقيم ل 9.

حسنًا، بعد هذه الجولة الأولى من التقييم، لدينا:

(call-1 square 9)

لتقييم هذا، ندعو نداء-1 مع حجتين، مربع و 9.التقديم نداء-1 يعطينا:

(square 9)

منذ هذا ما نداء-1 يفعل - فهو يستدعي الوسيطة الأولى مع الوسيطة الثانية.الآن، مربع من 9 يكون 81, ، وهي قيمة التعبير بأكمله.

ربما يساعد ترجمة هذا الرمز إلى LISP المشتركة على توضيح سلوكه:

((lambda (x y) (funcall x y)) (lambda (x) (* x x)) (* 3 3))

أو حتى أكثر صراحة:

(funcall (lambda (x y) (funcall x y))
         (lambda (x) (* x x))
         (* 3 3))

في الواقع ، لا يفعل هذا اللبدا الأول أي شيء مفيد ، لأنه يتلخص في:

(funcall (lambda (x) (* x x)) (* 3 3))

الذي يساوي

(let ((x (* 3 3)))
  (* x x))

يساوي

(let ((x 9))
  (* x x))

يساوي

(* 9 9)

يساوي 81.

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

(define (square x) (* x x))

(define (call-with arg fun) (fun arg))

(call-with (* 3 3) square)

هل لا يزال يبدو غريبا؟

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