سؤال

أنا أعمل في طريقي من خلال كتاب جراهام "On Lisp" ولا أستطيع فهم المثال التالي في الصفحة 37:

If we define exclaim so that its return value
incorporates a quoted list,

(defun exclaim (expression)
  (append expression ’(oh my)))

>  (exclaim ’(lions and tigers and bears))
(LIONS AND TIGERS AND BEARS OH MY)
> (nconc * ’(goodness))
(LIONS AND TIGERS AND BEARS OH MY GOODNESS)

could alter the list within the function:

> (exclaim ’(fixnums and bignums and floats))
(FIXNUMS AND BIGNUMS AND FLOATS OH MY GOODNESS)

To make exclaim proof against such problems, it should be written:
(defun exclaim (expression)
  (append expression (list ’oh ’my)))

هل يفهم أي شخص ما يحدث هنا؟ هذا هو الشد بجدية مع النموذج العقلي الخاص بي لما يفعله الاقتباس.

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

المحلول

nconc هي عملية مدمرة تغير حجةها الأولى عن طريق تغيير ذيلها. في هذه الحالة ، هذا يعني أن القائمة الثابتة '(oh my) يحصل على ذيل جديد.

نأمل أن تجعل هذا أكثر وضوحا. إنه مثل هذا إلى حد ما:

; Hidden variable inside exclaim
oh_my = oh → my → nil

(exclaim '(lions and tigers and bears)) =
    lions → and → tigers → and → bears → oh_my

(nconc * '(goodness)) destructively appends goodness to the last result:
    lions → and → tigers → and → bears → oh → my → goodness → nil
so now, oh_my = oh → my → goodness → nil

استبدال '(oh my) مع (list 'oh 'my) يحدد هذا لأنه لم يعد هناك ثابت يتم مشاركته من قبل الجميع ومتنوعة. كل دعوة إلى exclaim يولد قائمة جديدة ( list الغرض من الوظيفة في الحياة هو إنشاء قوائم جديدة).

نصائح أخرى

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

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

دعنا نضع مسألة التجميع جانباً في الوقت الحالي والتركيز على مراحل القراءة والتقييم ، على افتراض (من أجل البساطة) أن إدخال المقيِّم هو قائمة هياكل البيانات التي يقرأها القارئ.

النظر في شكل (QUOTE x) أين x هو بعض تمثيل نصي لكائن. قد يكون هذا رمزًا حرفيًا كما في (QUOTE ABC), ، قائمة حرفية كما في (QUOTE (A B C)), ، سلسلة حرفية كما في (QUOTE "abc"), ، أو أي نوع آخر من الحرفي. في مرحلة القراءة ، سيقرأ القارئ النموذج كقائمة (اتصل به Form1) العنصر الأول هو الرمز QUOTE والذي هو العنصر الثاني هو الكائن x ' الذي تمثله النصي x. لاحظ أنني أقول على وجه التحديد أن الكائن x ' يتم تخزينه ضمن القائمة التي تمثل التعبير, ، أي إلى حد ما ، تم تخزينه كـ جزء من الكود نفسه.

الآن حان دور المقيِّم. مدخلات المقيِّم Form1, ، وهي قائمة. لذلك ينظر إلى العنصر الأول من Form1, ، وبعد تحديد أنه الرمز QUOTE, يعود نتيجة التقييم العنصر الثاني من القائمة. هذه هي النقطة الحاسمة. يقوم المقيِّم بإرجاع العنصر الثاني من القائمة المراد تقييمه ، وهو ما يقرأه القارئ في مرحلة التنفيذ الأولى (قبل التجميع!). هذا كل ما يفعله. لا يوجد سحر لذلك ، إنه بسيط للغاية ، وبشكل كبير ، لا يتم إنشاء كائنات جديدة ولا يتم نسخ أي منها موجود.

لذلك ، كلما قمت بتعديل "قائمة مقتبسة" ، فأنت تعدل الكود نفسه. يعد رمز التعديل الذاتي أمرًا مربكًا للغاية ، وفي هذه الحالة ، يكون السلوك غير محدد بالفعل (لأن ANSI Common LISP يسمح بتطبيقات وضع التعليمات البرمجية في ذاكرة القراءة فقط).

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

في lisp المشتركة.

يتذكر:

'(1 2 3 4)

أعلاه هو القائمة الحرفية. بيانات ثابتة.

(list 1 2 3 4)

القائمة هي وظيفة عند إرجاع المكالمات أ قائمة جديدة جديدة مع حججها كعناصر قائمة.

تجنب تعديل القوائم الحرفية. الآثار ليست موحدة. تخيل lisp التي تجمع جميع البيانات الثابتة في منطقة ذاكرة الكتابة فقط. تخيل lisp يأخذ قوائم ثابتة ومشاركتها عبر الوظائف.

(defun a () '(1 2 3)

(defun b () '(1 2 3))

قد يقوم برنامج التحويل البرمجي LISP بإنشاء قائمة واحدة تتقاسمها كلتا الوظيفتين.

إذا قمت بتعديل القائمة التي تم إرجاعها بواسطة الدالة أ

  • قد لا يتغير
  • قد يتغير
  • قد يكون خطأ
  • قد يغير أيضًا القائمة التي يتم إرجاعها بواسطة الوظيفة ب

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

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