سؤال

قرأت في مكان ما حيث قالت هيكي الغنية:

"أعتقد أن استمرار استمرار النظري بالنظرية، ولكن ليس في الممارسة العملية"

أنا لست على دراية باللبن.
1. هل لدى Clojure مستمرا؟
2. إذا لا، لا تحتاج إلى استمرار؟ لقد رأيت الكثير من الأمثلة الجيدة خاصة من هذا الشخص. وبعد ما هو البديل؟
3. إذا كانت الإجابة بنعم، هل هناك وثائق؟

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

المحلول

عند الحديث عن استمرار، عليك التمييز بين نوعين مختلفين منهم:

  • مستمرات من الدرجة الأولى - دعم استمرار متكامل بشدة باللغة (مخطط أو روبي). Clojure لا يدعم استمرار الدرجة الأولى.

  • أسلوب تمرين استمرار (CPS) - CPS هو مجرد أسلوب من الترميز وأي لغة تدعم وظائف مجهولة ستسمح لهذا النمط (الذي ينطبق على عباءة أيضا).

أمثلة:

-- Standard function
double :: Int -> Int
double x = 2 * x

-- CPS-function – We pass the continuation explicitly
doubleCPS :: Int -> (Int -> res) -> res
doubleCPS x cont = cont (2 * x)
; Call
print (double 2)

; Call CPS: Continue execution with specified anonymous function
double 2 (\res -> print res)

اقرأ استمرار على ويكيبيديا.

لا أعتقد أن المستمرات ضرورية لغرض جيد، ولكن بشكل خاص استمرار الدرجة الأولى و CPS في اللغات الوظيفية مثل Haskell يمكن أن تكون مفيدة للغاية (مثال بتراجع ذكي).

نصائح أخرى

لقد كتبت ميناء عباءة CL-COLT الذي يضيف استمرار لمشترك LISP.

https://github.com/swannodette/delimc.

هو استمرار ميزة ضرورية في اللغة؟

رقم الكثير من اللغات لا تملك استمرار.

إذا لم يكن هناك، لا تحتاج إلى استمرار؟ لقد رأيت الكثير من الأمثلة الجيدة خاصة من هذا الرجل. ما هو البديل؟

مكدس مكالمة

مستمرات مجردة

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

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

استمرار الدرجة الأولى

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

مشاكل مع استمرار الدرجة الأولى

في حين أن استمرار المستمرات من الدرجة الأولى هي أداة قوية ومفيدة في كثير من الحالات، فهناك أيضا بعض العيوب لفضحها بلغة:

  • قد يؤدي التجريدات المختلفة التي تم إنشاؤها على رأس المستمرات إلى سلوك غير متوقع / بلا معنى عند تألفه. على سبيل المثال، finally قد يتم تخطي كتلة إذا كنت أستخدم استمرار لإحباط حساب.
  • إذا تم طلب استمرار الحالي في أي وقت، فيجب تنظيم وقت تشغيل اللغة بحيث يكون من الممكن إنتاج بعض تمثيل بنية البيانات للاستمرار الحالي في أي وقت. هذا يضع درجة من العبء في وقت التشغيل للحصول على ميزة، من أجل أفضل أو أسوأ، يعتبر غالبا "غريبة". إذا تم استضافة اللغة (مثل Clojure مستضافة على JVM)، فيجب أن يكون هذا التمثيل قادرا على التملك داخل الإطار الذي يوفره منصة الاستضافة. قد تكون هناك أيضا ميزات أخرى ترغب لغة في الحفاظ عليها (على سبيل المثال، C Interop) التي تقيد مساحة الحلول. قضايا مثل هذه الزيادة من إمكانات "عدم تطابق المعوقات"، ويمكن أن تعقد بشدة تطوير حل أداء.

إضافة استمرار الدرجة الأولى إلى لغة

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

على سبيل المثال، ديفيد نولين delimc. تنفذ المكتبة مستمرات محددة من أجزاء من برنامج عباءة من خلال سلسلة من تحويلات الماكرو. في الوريد مماثل، لقد أهتم pulley.cps., ، وهو مترجم كاسو يحول الكود إلى CPS، إلى جانب مكتبة وقت التشغيل لدعم مزيد من ميزات العباء النواة (مثل معالجة الاستثناءات) بالإضافة إلى Interop مع رمز عباءة أصلي.

مشكلة واحدة مع هذا النهج هي كيفية التعامل مع الحدود بين رمز (Clojure) رمز وتحويل (CPS). على وجه التحديد، نظرا لأنك لا تستطيع التقاط استمرار الرمز الأصلي، فأنت بحاجة إلى عدم السماح (أو تقييدها بطريقة أو بأخرى) بلغة الأساس أو وضع عبء المستخدم الخاص بمستخدم ضمان السياق سيسمح بأي مواصلة يرغبون في التقاطها في الواقع يتم القبض عليه.

يميل Pulley.cps نحو الأخير، على الرغم من إجراء بعض المحاولات للسماح للمستخدم بإدارة هذا. على سبيل المثال، من الممكن عدم السماح لرمز CPS بالاتصال في التعليمات البرمجية الأصلية. بالإضافة إلى ذلك، يتم توفير آلية لتزويد إصدارات CPS من الوظائف الأصلية القائمة.

بلغة تتمتع بنظام نوع قوي بما فيه الكفاية (مثل Haskell)، من الممكن استخدام نظام النوع لتغليف الحسابات التي قد تستخدم عمليات التحكم (أي استمرار) من التعليمات البرمجية النقية الوظيفية.

ملخص

لدينا الآن المعلومات اللازمة للإجابة مباشرة على الأسئلة الثلاثة الخاصة بك:

  1. Clojure لا يدعم استمرار الدرجة الأولى بسبب الاعتبارات العملية.
  2. يتم بناء جميع اللغات على استمرار المعنى النظري، لكن عدد قليل من اللغات تعرض استمرار كائنات من الدرجة الأولى. ومع ذلك، من الممكن إضافة استمرار إلى أي لغة عبر، على سبيل المثال، التحول إلى CPS.
  3. تحقق من الوثائق ل delimc. و / أو pulley.cps..

الاستخدام المشترك للسادان هو في تنفيذ هياكل التحكم من أجل: العودة من وظيفة، وكسر من حلقة، ومناولة الاستثناءات وما إلى ذلك. توفر معظم اللغات (مثل Java، C ++، إلخ) هذه الميزات كجزء من اللغة الأساسية. بعض اللغات لا (على سبيل المثال: مخطط). بدلا من ذلك، تعرض هذه اللغات استمرارية ككائنات من الدرجة الأولى والسماح للمبرمج بتحديد هياكل التحكم الجديدة. وبالتالي يجب النظر إلى مخطط كمجموعة لغات لغة البرمجة، وليس لغة كاملة في حد ذاتها.

في Clojure، لا نحتاج أبدا إلى استخدام المستمرات مباشرة، لأنه يتم توفير جميع هياكل التحكم تقريبا بواسطة مجموعة اللغة / VM. ومع ذلك، يمكن أن تكون مستمرات الطبقة الأولى أداة قوية في أيدي المبرمج المختص. خاصة في المخطط، المستمرات أفضل من النظراء المكافئ بلغات أخرى (مثل زوج SetJMP / LongJMP في ج). هذه المادة لديها المزيد من التفاصيل حول هذا الموضوع.

راجع للشغل، سيكون من المثير للاهتمام معرفة مدى غني هيكي يبرر رأيه في استمرار. أي روابط لذلك؟

كلوي (أو بالأحرى clojure.contrib.monads) لديه استمرار مناد إليك مقال يصف استخدامه والدافع.

حسنا ... كلوكور -> تنفذ ما أنت بعد ... ولكن مع ماكرو بدلا من ذلك

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