Rust: تعليم rustc لعمل مكالمات الذيل

تم إنشاؤها على ٢٧ يناير ٢٠١١  ·  18تعليقات  ·  مصدر: rust-lang/rust

لا يعرف Rustc كيفية إجراء مكالمات الذيل ("كن" بدلاً من "ret") حتى الآن. لا ينبغي أن يكون من الصعب تعليمها كيف.

A-LLVM

التعليق الأكثر فائدة

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

في 3 آب (أغسطس) 2016 ، 19:46 -0400 ، كتب أنطوان PLASKOWSKI [email protected] :

انا اخبار في الصدأ وانا حزين جدا. أحاول استخدام وظيفة تكرارية الذيل وأقوم بتكديس الفائض بسرعة كبيرة. أسوأ عندما أقوم بتجميع تغيير السلوك في الإصدار. هو فقط لا يستدعي وظيفتي. قال لي صديق أن LLVM يحسن إلى قيمة غير محددة (تعرف LLVM أن التكرار الذيل لانهائي؟!؟).

fn rec (i: i32) {rec (i + 1)} fn main () {println! ("{}"، rec (0)) ؛ }

أنا أتفق مع Boiethios ، وهي لغة ذات ميزات وظيفية لا تنفذ استدعاء الذيل تفوت شيئًا ما.

أنا أكتب بلغة C و C ++ ، فهم لا يضمنون الاتصال الذيل ولكنهم في الواقع يتعاملون معه بشكل جيد للغاية. لن يمنعني ذلك من تعلم الصدأ ، والآن أعلم أن الصدأ لا يتعامل معه ، سأقوم بالشفرة بدونه ، لذا فهي ليست مشكلة كبيرة.

لكني أعتقد أن هذه ميزة جيدة جدًا للغة حديثة.

-
أنت تتلقى هذا لأنك مشترك في هذا الموضوع.
قم بالرد على هذه الرسالة الإلكترونية مباشرةً ، أو قم بعرضها على GitHub (https://github.com/rust-lang/rust/issues/217#issuecomment-237409642) ، أو تجاهل الموضوع (https://github.com/notifications/unsubscribe -auth / AABsipoedHrbnKDekmzCr-dl8M6g-Gojks5qcShKgaJpZM4AC-q_).

ال 18 كومينتر

بير جرايدون ، نحن بحاجة إلى مزيد من التفكير حول استدعاء الاتفاقيات قبل تنفيذ ذلك. تتطلب LLVM اتفاقية fastcc لتنفيذ استدعاءات الذيل ، لكنها لا تفعل ما نريده تمامًا:

جرايدون: برسون: انطلاقا من التعليقات في llvm-land ، قد نكون في مأزق. قد نكون قادرين على تعويض ما تفعله fastcc اليوم ، لكن يسمح لها بتغيير رأيها غدًا.
Graydon: اعتقدت أن fastcc == x86_fastcall ، لكنني كنت مخطئًا.
Graydon: هذه اصطلاحات استدعاء مختلفة. fastcc هي "كل ما تشعر به هذا الأسبوع"
Graydon: نحتاج إلى التبديل إلى x86_fastcall وبعد ذلك ، على المدى الطويل ، كتابة اصطلاح الاتصال الخاص بنا.

هذا حاليًا نصف مطبق بسبب بعض المضاعفات في طريقة تعامل LLVM مع المكالمات الخلفية. يوزع Rustc تعبيرات 'be' ويترجمها كأزواج call + ret ، وهو ما يكفي لحثنا على "العمل" في حالات بسيطة وليست عميقة جدًا. قد يكون كافيا للتمهيد.

يبدو أن هناك نسخة واحدة فقط (fastcc) تدعم مكالمات الذيل المضمونة ، وللتكيف معها نحتاج إلى تغيير افتراضات ABI الخاصة بنا في عدة أماكن (تتحول إلى استعادة callee عند تمكين علامة -tailcallopt). لذا ، حتى إذا قمنا بتعليق أزواج call + ret الخاصة بنا بـ "tail" ، كما هو مطلوب ، لا يمكننا في الواقع إخبار LLVM بالبدء في تنفيذ هذا التحسين حتى الآن.

اتضح أنه لا يحتاج إلى تنفيذ أكثر مما هو موضح هنا للاستضافة الذاتية. التنقّل إلى المرحلة التالية.

هل يشعر أي شخص أننا سنقوم بهذا فعلاً بعد الآن؟

لا يبدو أنه سيحدث.

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

إنهم يعملون فقط مع مستوى ABI المستدعي الذي يعتبر دون المستوى الأمثل في الحالات التي لا تتطلب اتصالاً ذيلًا. لذا ، بمعنى ما ، نعم ، إنهم يطلبون إعلان المستدعي على أنه ذيل.

يمكننا تنفيذ ذلك ، على سبيل المثال ، من خلال تحليل صندوق وعندما نجد وظيفة تسمى ذيلًا ، إما تجميعها بشكل منفصل تحت اسم ABI الصديق إلى الذيل ، أو تجميع أغلفة تقوم بتبديل ABI عند الإدخال ، أو شيء من هذا القبيل. أو بدلاً من ذلك يمكننا تبديل وظيفة _ every_ في كل مكان إلى استخدام ABI المناسب للاتصال. لست متأكدًا مما إذا كنا نفعل ذلك حاليًا. كنا لبعض الوقت ولكن ربما توقفنا. إنها LLVM "fastcall" ABI ، والتي لا أعتقد أننا نستخدمها بعد الآن.

على أي حال ، هناك القليل من الفوضى.

لدينا تحسين مكالمة الأشقاء ، الآن. هل نخطط لمحاولة فعل المزيد؟

لن يحدث إلا بالقدر الذي تناوله رقم 2216. يجب أن يكون الحل رقم 2216 واسعًا بما يكفي لدعم ترميز آلة الحالة العامة.

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

أعتقد أن تعليق جرايدون على القائمة البريدية:

https://mail.mozilla.org/pipermail/rust-dev/2013-April/003557.html

يضع مسماراً في هذا التابوت. مستنسخة هنا:


في 10/04/2013 5:43 صباحًا ، كتبت Artella Coding:

مرحبا لا الصدأ تفعل الذيل التحسين؟ السبب الذي أطلبه هو ذلك
ينتج عن التنفيذ التكراري التالي لاستدعاء الذيل مكدس
تجاوز. شكرا.

لا ، ومن المحتمل جدًا ألا يحدث ذلك. لدينا خطأ طويل الأمد في هذا:

https://github.com/mozilla/rust/issues/217

بالإضافة إلى صفحة wiki والعديد من سلاسل رسائل القائمة البريدية:

https://github.com/mozilla/rust/wiki/Bikeshed-tailcall
https://mail.mozilla.org/pipermail/rust-dev/2011-August/000689.html
https://mail.mozilla.org/pipermail/rust-dev/2012-January/001280.html
...

وخلاصة كل هذا:

  • نعلم جميعًا أن مكالمات الذيل هي ميزة لغوية فاضلة.
    مزيد من التفصيل لفضائلهم ليست مطلوبة. كثير منا
    لديهم خلفيات Lisp و ML وسوف يحبونهم تمامًا. هم
    الغياب وجع قلب وحزن لا يصلان باستخفاف.
  • نداءات الذيل "تلعب بشكل سيئ" مع التدمير الحتمي. مشتمل
    قطرة حتمية من مربعات ~. كي لا نقول إنهم ليسوا كذلك
    قابلة للإنشاء ، ولكن خيارات تكوينها غير ملائمة لواجهة المستخدم ،
    معاقبة الأداء أو تعقيد الدلالات أو كل ما سبق.
  • مكالمات الذيل أيضًا "تلعب بشكل سيئ" مع الافتراضات في أدوات C ، بما في ذلك
    منصة ABIs والربط الديناميكي.
  • تتطلب مكالمات الذيل اصطلاح استدعاء يمثل نتيجة أداء
    فيما يتعلق باتفاقية C.
  • نجد أن معظم حالات الذيل _recursion_ يتم تحويلها بشكل جيد إلى ملف
    الحلقات ، ومعظم حالات ترميز المكالمات الخلفية غير المتكررة
    الآلات التي تحول بشكل جيد إلى حلقات ملفوفة حولها
    تعداد. ليست أي منهما _quite_ جميلة مثل
    المتغيرات التي تستخدم استدعاء الذيل ، لكنها تعمل وهي "سريعة" * ،
    وكذلك اصطلاحي لمبرمجي C و C ++ (الذين هم لدينا
    الجمهور الأساسي).

يؤسفني أن أقول كل هذا ، وبقلب مثقل ، لكننا نحن
حاولت ولم تجد طريقة لإجراء المفاضلات المرتبطة بها
تلخيص حجة للتضمين في الصدأ.

-جريدون

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

ربما تجدر الإشارة إلى أن Haskell يحتاج عادةً إلى تحويل ثابت للحجة للتضمين والدمج وما إلى ذلك. http://stackoverflow.com/a/9660027/667457

يمكن أن يدعم Rust تحويل الوسيطة الثابتة بالقول إن الوظائف المحددة داخل وظيفة أخرى يجب أن تكون قابلة للتحسين من أجل تحسين Tailcall. أو ببساطة حذر إذا كانت المكالمات الخلفية بين الوظائف المتداخلة داخل وظيفة أخرى فشلت في تحسين الأخوة. لست متأكدا من الوضع الحالي.

إنه لأمر محزن أن التكرار الذيل لن يتم تنفيذه. ثم لدي سؤال: لماذا إنشاء بناء جملة لغة يبدو وكأنه بناء جملة لغة وظيفي إذا كانت تفتقر إلى ميزة أساسية للوظيفة؟

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

fn rec(i: i32) {
  rec(i + 1)
}

fn main() {
  println!("{}", rec(0));
}

أتفق مع Boiethios ، وهي لغة ذات ميزات وظيفية لا تنفذ استدعاء الذيل تفوت شيئًا ما.

أنا أكتب بلغة C و C ++ ، فهم لا يضمنون الاتصال الذيل ، لكنهم في الواقع يتعاملون معه بشكل جيد للغاية. لن يمنعني من تعلم الصدأ ، الآن أعرف أن الصدأ لا يتعامل معه. سأقوم بالبرمجة بدون ذلك فهي ليست مشكلة كبيرة.

لكني أعتقد أن هذه ميزة جيدة جدًا للغة حديثة.

لاحظ أن

fn rec(i: i32) {
  println!("Hello");
  rec(i + 1)
}

كومة الفائض أيضًا في وضع تحرير البضائع

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

في 3 آب (أغسطس) 2016 ، 19:46 -0400 ، كتب أنطوان PLASKOWSKI [email protected] :

انا اخبار في الصدأ وانا حزين جدا. أحاول استخدام وظيفة تكرارية الذيل وأقوم بتكديس الفائض بسرعة كبيرة. أسوأ عندما أقوم بتجميع تغيير السلوك في الإصدار. هو فقط لا يستدعي وظيفتي. قال لي صديق أن LLVM يحسن إلى قيمة غير محددة (تعرف LLVM أن التكرار الذيل لانهائي؟!؟).

fn rec (i: i32) {rec (i + 1)} fn main () {println! ("{}"، rec (0)) ؛ }

أنا أتفق مع Boiethios ، وهي لغة ذات ميزات وظيفية لا تنفذ استدعاء الذيل تفوت شيئًا ما.

أنا أكتب بلغة C و C ++ ، فهم لا يضمنون الاتصال الذيل ولكنهم في الواقع يتعاملون معه بشكل جيد للغاية. لن يمنعني ذلك من تعلم الصدأ ، والآن أعلم أن الصدأ لا يتعامل معه ، سأقوم بالشفرة بدونه ، لذا فهي ليست مشكلة كبيرة.

لكني أعتقد أن هذه ميزة جيدة جدًا للغة حديثة.

-
أنت تتلقى هذا لأنك مشترك في هذا الموضوع.
قم بالرد على هذه الرسالة الإلكترونية مباشرةً ، أو قم بعرضها على GitHub (https://github.com/rust-lang/rust/issues/217#issuecomment-237409642) ، أو تجاهل الموضوع (https://github.com/notifications/unsubscribe -auth / AABsipoedHrbnKDekmzCr-dl8M6g-Gojks5qcShKgaJpZM4AC-q_).

مجرد سؤال: من الممكن نظريًا إجراء تحليل الرسم البياني واستدعاء المكالمات الخلفية إلى حلقات ، على الأقل داخل صندوق واحد ، ولكنها مكلفة من الناحية الحسابية في وقت الترجمة وصعبة جدًا في البرمجة. هل كان هناك أي نقاش حول هذا الاحتمال؟ سيظل هذا خيارًا الآن ، بغض النظر عن خيار استدعاء الاتفاقية.

يتمثل نهج lbstanza في طلب شرح توضيحي للوظائف لجعلها مؤهلة للتكلفة الإجمالية للملكية (defn + بدلاً من defn). في حالة الصدأ ، سيؤدي ذلك إلى التخفيف إلى حد كبير من وقت التجميع الإضافي الذي يستغرقه اقتراح Timthelion ، طالما أنك لا تستخدم مكالمات الذيل حرفيًا في كل مكان.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات