لغة البرمجة LFE
لغة إرلانج بنكهة ليسب ( LFE ) هي لغة برمجة وظيفية ، متزامنة ، ذات إدارة تلقائية للذاكرة ، ومتعددة الأغراض، وهي لهجة من لغة ليسب مبنية على إرلانج الأساسية وآلة إرلانج الافتراضية ( BEAM ). تعتمد LFE على إرلانج لتوفير بنية ليسب لكتابة تطبيقات موزعة، مقاومة للأعطال ، تعمل في الوقت الحقيقي المرن ، ومتواصلة. كما تُوسّع LFE لغة إرلانج لدعم البرمجة الوصفية باستخدام وحدات ليسب البرمجية، وتوفير تجربة تطوير محسّنة من خلال حلقة قراءة-تقييم-طباعة غنية بالميزات (REPL). [ 1 ] يتم دعم LFE بشكل فعال على جميع الإصدارات الحديثة من إرلانج؛ وأقدم إصدار مدعوم من إرلانج هو R14.
تاريخ

الإصدار الأولي
بدأ العمل الأولي على LFE في عام 2007، عندما شرع روبرت فيردينغ في إنشاء نموذج أولي للغة ليسب تعمل على إرلانج. [ 2 ] ركز هذا العمل بشكل أساسي على التحليل اللغوي واستكشاف الشكل الذي قد يبدو عليه التنفيذ. لم يكن هناك نظام للتحكم في الإصدارات مستخدمًا في ذلك الوقت، لذا فإن تتبع التواريخ الأولية الدقيقة يمثل إشكالية إلى حد ما. [ 2 ]
أعلن فيردينغ عن الإصدار الأول من LFE على قائمة بريد أسئلة إرلانج في مارس 2008. [ 3 ] كان هذا الإصدار من LFE محدودًا للغاية: لم يكن يدعم letrecعمليات التكرار، أو binaryعمليات التكرار، أو عمليات التكرار receive، أو tryعمليات التكرار؛ كما أنه لم يكن يدعم واجهة سطر أوامر ليسب. [ 4 ]
تم تطوير LFE مبدئيًا باستخدام الإصدار R12B-0 من لغة إرلانج [ 5 ] على جهاز كمبيوتر محمول من نوع ديل إكس بي إس. [ 4 ]
| 1958 | 1960 | 1965 | 1970 | 1975 | 1980 | 1985 | 1990 | 1995 | 2000 | 2005 | 2010 | 2015 | 2020 | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| LISP 1، 1.5، LISP 2 (مهجورة) | |||||||||||||||
| ماكليس | |||||||||||||||
| تداخل | |||||||||||||||
| MDL | |||||||||||||||
| آلة التأتأة | |||||||||||||||
| مخطط | R5RS | R6RS | R7RS صغير | ||||||||||||
| لا شيء | |||||||||||||||
| ZIL (لغة تنفيذ Zork) | |||||||||||||||
| فرانز ليسب | |||||||||||||||
| muLisp | |||||||||||||||
| لغة الشفرة الشائعة | معيار ANSI | ||||||||||||||
| لي لِسْب | |||||||||||||||
| مخطط معهد ماساتشوستس للتكنولوجيا | |||||||||||||||
| XLISP | |||||||||||||||
| تي | |||||||||||||||
| شيز سكيم | |||||||||||||||
| إيماكس ليسب | |||||||||||||||
| أوتو ليسب | |||||||||||||||
| PicoLi sp | |||||||||||||||
| غامبيت | |||||||||||||||
| EuLisp | |||||||||||||||
| لغة ISLISP | |||||||||||||||
| أوبن ليسب | |||||||||||||||
| مخطط PLT | مضرب | ||||||||||||||
| لغة نيو ليسب | |||||||||||||||
| جنو غايل | |||||||||||||||
| لغة ليسب المرئية | |||||||||||||||
| كلوجر | |||||||||||||||
| قوس | |||||||||||||||
| LFE | |||||||||||||||
| هي | |||||||||||||||
الدوافع
صرح روبرت فيردينج أن هناك عدة أسباب دفعته إلى بدء لغة البرمجة LFE: [ 2 ]
- كان لديه خبرة سابقة في البرمجة بلغة ليسب.
- نظراً لخبرته السابقة، كان مهتماً بتطبيق لغة ليسب الخاصة به.
- على وجه الخصوص، أراد تنفيذ لغة Lisp في Erlang: لم يكن فضوليًا فقط لمعرفة كيف ستعمل وتتكامل مع Erlang، بل أراد أيضًا أن يرى كيف ستبدو .
- منذ أن ساعد في إنشاء لغة البرمجة Erlang، كان لديه هدف يتمثل في إنشاء لغة Lisp مصممة خصيصًا للعمل على BEAM وقادرة على التفاعل بشكل كامل مع Erlang/OTP.
- أراد تجربة ترجمة لغة أخرى على إرلانج. ولذلك، رأى في LFE وسيلة لاستكشاف ذلك من خلال توليد كور إرلانج ودمجها في الواجهة الخلفية لمترجم إرلانج.
سمات
- لغة تستهدف آلة إرلانج الافتراضية (BEAM)
- تكامل سلس مع لغة إرلانج : استدعاءات دوال إرلانج بدون أي تكلفة إضافية (والعكس صحيح)
- البرمجة الوصفية عبر وحدات ماكرو لغة ليسب وتماثل الأيقونية في لغة ليسب
- توثيق على نمط لغة Common Lisp من خلال كل من تعليقات الكود المصدري وسلاسل التوثيق
- البرمجة المتزامنة باستخدام بنية لا تشارك فيها أي بيانات عبر تمرير الرسائل ( نموذج الممثل )
- التركيز على الاستدعاء الذاتي والوظائف ذات الرتبة العليا بدلاً من الحلقات القائمة على التأثيرات الجانبية
- حلقة قراءة-تقييم-طباعة كاملة (REPL) للتطوير والاختبار التفاعلي (على عكس غلاف Erlang، فإن LFE REPL يدعم تعريفات الوظائف والماكرو)
- مطابقة الأنماط
- تحميل الكود أثناء التشغيل
- فصل مساحات الأسماء للمتغيرات والدوال في لغة Lisp -2
- التشغيل البيني لجافا عبر JInterface و Erjang
- مهارات البرمجة النصية
lfeمع كليهما وlfescript
بناء الجملة والدلالات
التعبيرات الرمزية (التعبيرات الرمزية)
مثل لغة ليسب، تُعدّ لغة LFE لغةً مُوجّهةً نحو التعبيرات . وعلى عكس لغات البرمجة غير المتجانسة ، لا تُفرّق لغات ليسب، أو تُفرّق بشكلٍ طفيف، بين التعبيرات والعبارات من الناحية النحوية : فجميع التعليمات البرمجية والبيانات تُكتب على شكل تعبيرات. وقد أدخلت LFE خاصية التجانس إلى آلة إرلانج الافتراضية.
القوائم
في لغة LFE، يُكتب نوع بيانات القائمة بحيث تُفصل عناصرها بمسافات بيضاء، وتُحاط بأقواس. على سبيل المثال، `foo` هي قائمة عناصرها هي العددان الصحيحان ` foo` و` foo`، بالإضافة إلى الذرة `[[foo| ]`. هذه القيم مُعرّفة ضمنيًا: فهي على التوالي عددان صحيحان ونوع بيانات خاص بلغة Lisp يُسمى الذرة الرمزية ، ولا يلزم تعريفها على هذا النحو.(list12'foo)12foo
كما هو موضح في المثال أعلاه، تُكتب تعابير LFE على شكل قوائم باستخدام تدوين البادئة . العنصر الأول في القائمة هو اسم الصيغة ، أي دالة أو عامل أو ماكرو. أما باقي عناصر القائمة فهي الوسائط.
المشغلون
تُستخدم عوامل LFE-Erlang بنفس الطريقة. التعبير
( * ( + 1 2 3 4 5 6 ) 2 )يتم تقييمها إلى 42. على عكس الدوال في Erlang و LFE، فإن عوامل التشغيل الحسابية في Lisp متغيرة (أو n-ary )، قادرة على أخذ أي عدد من الوسائط.
تعبيرات لامدا وتعريف الدوال
يحتوي LFE على تعبيرات لامدا ، تمامًا مثل Common Lisp. ومع ذلك، فإنه يحتوي أيضًا على lambda-match لمراعاة قدرات مطابقة الأنماط في Erlang في استدعاءات الدوال المجهولة.
مصطلحات إرلانج في اللغة الإنجليزية
لا يمثل هذا القسم مقارنة كاملة بين Erlang و LFE، ولكنه يعطي فكرة عامة.
مطابقة الأنماط
إرلانج:
1 > { لين , الحالة , رسالة } = { 8 , حسنا , "تريليان" }. { 8 , حسنًا , "تريليان" } 2 > رسالة . "تريليان"LFE:
lfe> ( set ( tuple len status msg ) #( 8 ok "Trillian" )) lfe> ;; أو باستخدام صيغة LFE الحرفية للصف: lfe> ( set `#(, len , status , msg ) #( 8 ok "Trillian" )) #( 8 ok "Trillian" ) lfe> msg "Trillian"فهم القوائم
إرلانج:
1 > [ الجذع ( الرياضيات : الأسرى ( 3 , X )) || X <- [ 0 , 1 , 2 , 3 ]]. [ 1 , 3 , 9 , 27 ]LFE:
lfe> ( list-comp (( <- x ' ( 0 1 2 3 ))) ( trunc ( math:pow 3 x ))) ( 1 3 9 27 )أو أسلوب وظيفي اصطلاحي:
lfe> ( lists:map ( lambda ( x ) ( trunc ( math:pow 3 x ))) ' ( 0 1 2 3 )) ( 1 3 9 27 )حراس
إرلانج:
right_number ( X ) when X == 42 ; X == 276709 -> true ; right_number (_) -> false .LFE:
( defun right-number? (( x ) ( when ( orelse ( == x 42 ) ( == x 276709 ))) 'true ) (( _ ) 'false ))الاستبعاد في رؤوس الوظائف
إرلانج:
sum ( L ) -> sum ( L , 0 ). sum ([], Total ) -> Total ; sum ([ H | T ], Total ) -> sum ( T , H + Total ).LFE:
( مجموع ديفون ( ل ) ( مجموع ل 0 )) ( مجموع ديفون (( ' () إجمالي ) إجمالي ) ((( سلبيات h t ) إجمالي ) ( مجموع t ( + h إجمالي ))))أو باستخدام قيمة حرفية "cons" بدلاً من صيغة المُنشئ:
( مجموع ديفون ( ل ) ( مجموع ل 0 )) ( مجموع ديفون (( ' () إجمالي ) إجمالي ) (( ` ( , h . , t ) إجمالي ) ( مجموع t ( + h إجمالي ))))مطابقة السجلات في رؤوس الوظائف
إرلانج:
handle_info ( ping , #state { remote_pid = undefined } = State ) -> gen_server : cast ( self (), ping ), { noreply , State }; handle_info ( ping , State ) -> { noreply , State };LFE:
( defun handle_info (( 'ping ( = ( match-state remote-pid 'undefined ) state )) ( gen_server:cast ( self ) 'ping ) `#( noreply , state )) (( 'ping state ) `#( noreply , state )))استقبال الرسائل
إرلانج:
universal_server () -> receive { become , Func } -> Func () end .LFE:
( defun universal-server () ( receive (( tuple 'become func ) ( funcall func ))))أو:
( defun universal-server () ( receive ( `#( become , func ) ( funcall func ))))أمثلة
قابلية التشغيل البيني لـ Erlang
تأخذ استدعاءات دوال إرلانج الشكل التالي : (<الوحدة النمطية>:<الدالة> <الوسيط1> ... <الوسيط>) :
( io:format "Hello, World!" )النموذج الوظيفي
استخدام الاستدعاء الذاتي لتعريف دالة أكرمان :
( defun ackermann (( 0 n ) ( + n 1 )) (( m 0 ) ( ackermann ( - m 1 ) 1 )) (( m n ) ( ackermann ( - m 1 ) ( ackermann m ( - n 1 )))))دوال التأليف:
( defun compose ( f g ) ( lambda ( x ) ( funcall f ( funcall g x ))))( defun check () ( let* (( sin-asin ( compose #' sin/1 #' asin/1 )) ( expected ( sin ( asin 0.5 ))) ( compose-result ( funcall sin-asin 0.5 ))) ( io:format "الإجابة المتوقعة: ~p~n" ( list expected )) ( io:format "الإجابة مع compose: ~p~n" ( list compose-result ))))التزامن
تمرير الرسائل باستخدام "العمليات" الخفيفة الوزن في لغة إرلانج:
( defmodule messenger-back ( export ( print-result 0 ) ( send-message 2 )))( defun print-result () ( receive (( tuple pid msg ) ( io:format "تم استلام الرسالة: '~s'~n" ( list msg )) ( io:format "إرسال رسالة إلى العملية ~p ...~n" ( list pid )) ( ! pid ( tuple msg )) ( print-result ))))( defun send-message ( calling-pid msg ) ( let (( spawned-pid ( spawn 'messenger-back 'print-result ()))) ( ! spawned-pid ( tuple calling-pid msg ))))طلبات HTTP متعددة متزامنة:
( defun parse-args ( flag ) "بالنظر إلى وسيط واحد أو أكثر من وسائط سطر الأوامر، استخرج القيم التي تم تمريرها. على سبيل المثال، إذا تم تمرير ما يلي عبر سطر الأوامر: $ erl -my-flag my-value-1 -my-flag my-value-2 ويمكن استخراجه بعد ذلك في برنامج LFE عن طريق استدعاء هذه الدالة: (let ((args (parse-args 'my-flag))) ... ) في هذا المثال، ستكون القيمة المُسندة إلى المتغير arg قائمةً تحتوي على القيمتين my-value-1 و my-value-2. ( let (( `#( ok , data ) ( init:get_argument flag ))) ( lists:merge data )))( defun get-pages () "بدون وسيط، افترض أن المعامل 'url' قد تم تمريره عبر سطر الأوامر." ( let (( urls ( parse-args 'url ))) ( get-pages urls )))( defun get-pages ( urls ) "ابدأ inets وقم بإجراء (عدد كبير من) طلبات HTTP." ( inets:start ) ( plists:map ( lambda ( x ) ( get-page x )) urls ))( defun get-page ( url ) "إجراء طلب HTTP واحد." ( let* (( method 'get ) ( headers ' ()) ( request-data `#(, url , headers )) ( http-options ()) ( request-options ' ( #( sync false )))) ( httpc:request method request-data http-options request-options ) ( receive ( `#( http #(, request-id #( error , reason ))) ( io:format "Error: ~p~n" ` ( , reason ))) ( `#( http #(, request-id , result )) ( io:format "Result: ~p~n" ` ( , result ))))))مراجع
- ↑ فيردينغ، روبرت. "إرلانج بنكهة اللثغة" (ملف PDF) . مصنع إرلانج . تم الاسترجاع في 17 يناير 2014 .
- 1 2 3 "تاريخ LFE على قائمة بريد Lisp Flavored Erlang" . تم الاسترجاع في 28-05-2014 .
- ↑ "إعلان LFE على قائمة بريد أسئلة إرلانج" . تم الاطلاع عليه بتاريخ 17-01-2014 .
- 1 2 أرمسترونغ، جو؛ فيردينغ، روبرت (30 ديسمبر 2013). "الأجهزة المستخدمة في تطوير إرلانج وLFE" (مراسلات بريد إلكتروني). مقابلة أجراها دنكان ماكجريجور . تاريخ الاسترجاع: 17 يناير 2014 .
- ↑ "متابعة لإعلان LFE على قائمة بريد أسئلة إرلانج" . تم الاطلاع عليه بتاريخ 17-01-2014 .
روابط خارجية
- الموقع الرسمي
- LFE على GitHub
- دليل البدء السريع لتقنية LFE
- دليل مستخدم LFE
- LFE على Rosetta Code
- لغات البرمجة
- لغات برمجة مطابقة الأنماط
- عائلة لغات البرمجة ليسب
