التماثل الأيقوني

في برمجة الحاسوب ، تُعدّ خاصية التماثل (من الكلمتين اليونانيتين homo- بمعنى "نفس الشيء" و icon بمعنى "تمثيل") خاصية غير رسمية لبعض لغات البرمجة . تُوصف اللغة بأنها متماثلة إذا أمكن التعامل مع برنامج مكتوب بها كبيانات باستخدام تلك اللغة. [ 1 ] وبالتالي، يمكن استنتاج التمثيل الداخلي للبرنامج بمجرد قراءته. غالبًا ما تُلخّص هذه الخاصية بالقول إن اللغة تُعامل الشيفرة البرمجية كبيانات . تنشأ عدم رسمية هذه الخاصية من كونها، من الناحية النظرية، تنطبق على جميع لغات البرمجة تقريبًا. لا يوجد إجماع على تعريف دقيق لهذه الخاصية. [ 2 ] [ 3 ]

في اللغات المتجانسة، يُمثَّل التمثيل الأساسي للبرامج أيضًا كبنية بيانات ضمن نوع بيانات بدائي في اللغة نفسها. [ 1 ] وهذا يُسهِّل البرمجة الوصفية مقارنةً باللغات التي تفتقر إلى هذه الخاصية: إذ يعتمد الانعكاس في اللغة (فحص كيانات البرنامج أثناء التشغيل ) على بنية واحدة متجانسة، ولا يتطلب التعامل مع بنى متعددة مختلفة قد تظهر في بنية معقدة. عادةً ما تدعم اللغات المتجانسة وحدات الماكرو النحوية بشكل كامل ، مما يسمح للمبرمج بالتعبير عن تحويلات البرامج بإيجاز.

من الأمثلة الشائعة لغة ليسب ، التي صُممت لتسهيل التعامل مع القوائم، حيث تُحدد بنيتها بواسطة تعابير S التي تأخذ شكل قوائم متداخلة ، ويمكن معالجتها بواسطة أكواد ليسب أخرى. [ 4 ] ومن الأمثلة الأخرى لغات البرمجة كلوجر (لهجة معاصرة من ليسب)، وريبول (وكذلك ريد التي خلفتها )، وريفال ، وبرولوج ، و XSLT ، وربما جوليا (انظر قسم "أساليب التنفيذ" لمزيد من التفاصيل).

تاريخ

ظهر المصطلح لأول مرة فيما يتعلق بلغة برمجة TRAC ، التي طورها كالفن مويرز : [ 5 ]

كان أحد الأهداف الرئيسية للتصميم هو أن يكون نص الإدخال الخاص بـ TRAC (ما يكتبه المستخدم) مطابقًا تمامًا للنص الذي يوجه العمل الداخلي لمعالج TRAC. بعبارة أخرى، يجب تخزين إجراءات TRAC في الذاكرة كسلسلة من الأحرف تمامًا كما كتبها المستخدم على لوحة المفاتيح. إذا تطورت إجراءات TRAC نفسها إلى إجراءات جديدة، فيجب أيضًا كتابة هذه الإجراءات الجديدة بنفس النص. يفسر معالج TRAC هذا النص أثناء عمله على أنه برنامجه. بعبارة أخرى، يقوم برنامج مترجم TRAC (المعالج) بتحويل الحاسوب فعليًا إلى حاسوب جديد بلغة برمجة جديدة - لغة TRAC. في أي وقت، يجب أن يكون من الممكن عرض معلومات البرنامج أو الإجراءات بنفس الشكل الذي سيتعامل معه معالج TRAC أثناء تنفيذه. من المستحسن أن يكون تمثيل رمز الأحرف الداخلي مطابقًا أو مشابهًا جدًا لتمثيل الرمز الخارجي. في تطبيق TRAC الحالي، يعتمد تمثيل الأحرف الداخلي على ASCII . لأن إجراءات TRAC والنصوص لها نفس التمثيل داخل المعالج وخارجه، فإن مصطلح homoiconic قابل للتطبيق، حيث تعني كلمة homo نفس الشيء، وتعني كلمة icon التمثيل.

الجملة الأخيرة أعلاه مصحوبة بالحاشية رقم 4، والتي تُشير إلى أصل المصطلح: [ أ ]

بناءً على اقتراح ماكولوغ دبليو  إس، استنادًا إلى المصطلحات التي وضعها بيرس، سي  إس.

قد يكون الباحثان المذكوران في هذا الاقتباس هما عالم وظائف الأعصاب وعالم التحكم الآلي وارن ستورجيس ماكولوتش (لاحظ اختلاف اللقب عن الملاحظة) والفيلسوف والمنطقي والرياضي تشارلز ساندرز بيرس . [ 2 ] وقد استخدم بيرس بالفعل مصطلح "الأيقونة" في نظريته السيميائية . ووفقًا لبيرس، توجد ثلاثة أنواع من العلامات في التواصل: الأيقونة، والمؤشر، والرمز. الأيقونة هي أبسط تمثيل: فهي تشبه ماديًا ما تدل عليه.

استخدم آلان كاي مصطلح "homoiconic" وربما ساهم في نشره من خلال استخدامه لهذا المصطلح في أطروحته للدكتوراه عام 1969: [ 7 ]

تُعدّ لغة ليسب التفاعلية [...] وTRAC استثناءً بارزًا لجميع الأنظمة السابقة. فكلتاهما موجهتان وظيفيًا (إحداهما قائمة والأخرى سلسلة نصية)، وتتواصلان مع المستخدم بلغة واحدة، وتتميزان بتماثلهما الداخلي والخارجي. كما تتمتعان بالقدرة على إنشاء وظائف جديدة ديناميكيًا، والتي يمكن تطويرها لاحقًا حسب رغبة المستخدم. أما عيبهما الوحيد فهو أن البرامج المكتوبة بهما تبدو وكأنها رسالة الملك برنيبوريخ إلى السومريين مكتوبة بالخط المسماري البابلي! [...]

الاستخدامات والمزايا

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

يُعد المُقيِّم الدائري الفائق مثالاً نموذجياً على التماثل المخروطي .

أساليب التنفيذ

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

تستخدم لغات مثل Lisp ولهجاتها، [ 8 ] مثل Scheme ، [ 9 ] Clojure ، و Racket تعبيرات S لتحقيق التماثل، وتعتبر "أنقى" أشكال التماثل، حيث تستخدم هذه اللغات نفس التمثيل لكل من البيانات والتعليمات البرمجية.

توفر لغات برمجة أخرى هياكل بيانات لتسهيل معالجة التعليمات البرمجية بكفاءة. ومن الأمثلة البارزة على هذا الشكل الأضعف من التماثل في السلاسل: جوليا ، ونيم ، وإلكسير .

تشمل اللغات التي غالباً ما تعتبر متجانسة القوام ما يلي:

في لغة ليسب

تستخدم لغة ليسب تعابير S كتمثيل خارجي للبيانات والتعليمات البرمجية. يمكن قراءة تعابير S باستخدام دالة ليسب الأساسية READ. READتُرجع هذه الدالة بيانات ليسب: قوائم، رموز ، أرقام، وسلاسل نصية. تستخدم دالة ليسب الأساسية EVALالتعليمات البرمجية ليسب المُمثلة كبيانات ليسب، وتحسب التأثيرات الجانبية، ثم تُرجع نتيجة. ستطبع الدالة الأساسية النتيجة PRINT، حيث تُنشئ تعبير S خارجيًا من بيانات ليسب.

بيانات لغة ليسب، وهي قائمة تستخدم أنواع بيانات مختلفة: (القوائم الفرعية)، والرموز، والسلاسل النصية، والأعداد الصحيحة.

(( :name "john" :age 20 ) ( :name "mary" :age 18 ) ( :name "alice" :age 22 ))

كود لغة ليسب. يستخدم المثال القوائم والرموز والأرقام.

( * ( الخطيئة ١.١ ) ( جتا ٢.٠٣ ) ) ؛ في infix: الخطيئة (1.1) * كوس (2.03)

أنشئ التعبير أعلاه باستخدام دالة Lisp الأساسية، LISTثم عيّن المتغير EXPRESSIONللنتيجة.

( setf expression ( list '* ( list 'sin 1.1 ) ( list 'cos 2.03 ) ) -> ( * ( SIN 1.1 ) ( COS 2.03 ) ) ; تقوم لغة Lisp بإرجاع وطباعة النتيجة( التعبير الثالث ) ؛ العنصر الثالث من التعبير -> ( جتا 2.03 )

غيّر COSالمصطلح إلىSIN

( setf ( first ( third expression )) 'SIN ) ; أصبح التعبير الآن (* (SIN 1.1) (SIN 2.03)).

قيّم التعبير

( تقييم التعبير ) -> 0.7988834

اطبع التعبير كسلسلة نصية

( تعبير الطباعة إلى سلسلة نصية ) -> "(* (SIN 1.1) (SIN 2.03))"

اقرأ التعبير من سلسلة نصية

( read-from-string "(* (SIN 1.1) (SIN 2.03))" ) -> ( * ( SIN 1.1 ) ( SIN 2.03 ) ) ; تُرجع قائمة من القوائم والأرقام والرموز

في لغة البرولوج

1 ؟- X يساوي 2*5. X = 10.2 ?- L = ( X is 2*5 ) , write_canonical ( L ) . is ( _, * ( 2 , 5 )) L = ( X is 2*5 ) .3 ?- L = ( ten ( X ) :- ( X is 2*5 )) , write_canonical ( L ) . :- ( ten ( A ) , is ( A, * ( 2 , 5 ))) L = ( ten ( X ) :-X is 2*5 ) .4 ?- L = ( ten ( X ) :- ( X is 2*5 )) , assert ( L ) . L = ( ten ( X ) :-X is 2*5 ) .5 ؟- عشرة ( س ) . س = 10.6 ؟-

في السطر 4، نُنشئ عبارة جديدة. :-يفصل المعامل رأس العبارة عن جسمها. باستخدام assert/1*، نضيفها إلى العبارات الموجودة (نضيفها إلى "قاعدة البيانات")، حتى نتمكن من استدعائها لاحقًا. في لغات برمجة أخرى، يُطلق على هذه العملية "إنشاء دالة أثناء التشغيل". يمكننا أيضًا حذف العبارات من قاعدة البيانات باستخدام abolish/1، أو retract/1.

* الرقم الذي يلي اسم العبارة هو عدد الوسائط التي يمكن أن تأخذها. ويُسمى أيضًا عدد الوسائط .

يمكننا أيضًا الاستعلام من قاعدة البيانات للحصول على نص جملة معينة:

7 ?- clause ( ten ( X ) , Y ) . Y = ( X is 2*5 ) .8 ?- clause ( ten ( X ) , Y ) , Y = ( X is Z ) . Y = ( X is 2*5 ) , Z = 2*5.9 ?- clause ( ten ( X ) , Y ) , call ( Y ) . X = 10 , Y = ( 10 is 2*5 ) .

callوهو مماثل لوظيفة لغة ليسب eval.

إنريبول

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

فيما يلي مثال على كود مكتوب بلغة Rebol (لاحظ أن هذا >>يمثل موجه المفسر؛ تمت إضافة مسافات بين بعض العناصر لتحسين سهولة القراءة):

>>repeati3 [ print [ i"hello" ] ] 1 مرحباً ٢ مرحباً 3 مرحباً

( repeatفي الواقع، هي دالة مدمجة في لغة Rebol وليست بنية لغوية أو كلمة مفتاحية).

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

[ كرر i 3 [ اطبع [ i "مرحباً" ]]] 

هذه الكتلة من النوع block! ويمكن أيضًا تعيينها كقيمة لكلمة باستخدام ما يبدو أنه صيغة للتعيين، ولكن المفسر يفهمها في الواقع على أنها نوع خاص ( set-word!) وتأخذ شكل كلمة متبوعة بنقطتين رأسيتين:

>> ;; قم بتعيين قيمة الكتلة للكلمة `block1`block1: [ repeati3 [ print [ i"hello" ] ] ] == [كرر i 3 [اطبع [i "مرحباً"]]] >> ;; قم بتقييم نوع الكلمة `block1`type?block1 == حظر!

لا يزال من الممكن تفسير الكتلة باستخدام doالدالة المتوفرة في Rebol (على غرار ما هو موجود evalفي Lisp ).

من الممكن فحص عناصر الكتلة وتغيير قيمها، وبالتالي تغيير سلوك الكود إذا تم تقييمه:

>> ;; العنصر الثالث من الكتلةblock1/3 == 3 >> ;; اضبط قيمة العنصر الثالث على 5block1/3:5 == 5 >> ;; عرض الكتلة المتغيرةprobeblock1 == [كرر i 5 [اطبع [i "مرحباً"]]] >> ;; تقييم الكتلةdoblock1 1 مرحباً ٢ مرحباً 3 مرحباً 4 مرحباً 5 مرحباً

انظر أيضاً

ملحوظات

  1. خلطت الإصدارات السابقة من صفحة ويكيبيديا هذه (2006-2023) بين الملاحظة رقم 5 غير ذات الصلة من ورقة TRAC المذكورة أعلاه، مما أدى إلى ادعاء خاطئ بأن مصطلح "homoiconic" نشأ في ورقة بحثية حول المعالجة الكلية لدوجلاس ماكلروي. لا تذكر تلك الورقة أي مصطلحات مشابهة ولو من بعيد؛ فتأثيرها على عمل TRAC ذو طبيعة مختلفة. وقد تكرر هذا الادعاء لاحقًا في بعض المصادر. [ 6 ]

مراجع

  1. 1 2 سيرافولا، أنتونيلو؛ جوبلين، فرانك (2021). "من JSON إلى JSEN عبر اللغات الافتراضية" . المجلة المفتوحة لتقنيات الويب . 8 (1): 1-15 . في لغة متجانسة التماثل، يكون التمثيل الأساسي للبرامج هو أيضًا بنية بيانات في نوع بدائي من اللغة نفسها.
  2. 1 2 فان شيلفن، كلاس (2018/03/01). "لا تقل "Homoiconic""تم الاطلاع عليه بتاريخ 16 أكتوبر 2024. لسوء الحظ، هذا التعريف البسيط ليس التعريف الوحيد المستخدم حاليًا. في الواقع، هناك انتشار واسع لتعريفات بديلة، بل ومضللة تمامًا، بعضها لا يزال شائعًا.
  3. هيرمان، ديفيد (17 أبريل 2012). "التشابه في الشكل ليس هو المهم" . مؤرشف من الأصل في 11 أبريل 2024. تم الاطلاع عليه في 16 أكتوبر 2024. لم أفهم قط ما المقصود بـ "التشابه في الشكل" . غالبًا ما يقول الناس شيئًا مثل "يستخدم بناء الجملة أحد هياكل البيانات الأساسية للغة". هذا خطأ في التصنيف: بناء الجملة ليس هيكل بيانات، بل هو مجرد تمثيل للبيانات كنص.
  4. ويلر، ديفيد أ. "تعبيرات S-الليسب القابلة للقراءة" .
  5. مويرز، سي إن ؛ دويتش، إل بي (1965). "تراك، لغة لمعالجة النصوص". وقائع مؤتمر ACM الوطني العشرين لعام 1965. الصفحات 229-246 . doi : 10.1145/800197.806048 . 
  6. مانيرت، هيرويغ؛ مكغروارتي، كريس؛ غالانت، سكوت؛ دي كوك، كوين؛ غالولي، جيم؛ رافال، أنوب؛ سنيفلي، كيث (2022). "نحو برمجة فوقية تعاونية قابلة للتطوير: دراسة حالة لدمج بيئتين للبرمجة الفوقية" (ملف PDF) . المجلة الدولية للتطورات في البرمجيات . 15 : 128-140 . ISSN 1942-2628 . 
  7. كاي، آلان (1969). المحرك التفاعلي (دكتوراه). جامعة يوتا.
  8. 1 2 3 4 5 6 7 8 9 لغات متجانسة
  9. 1 2 اللغات المتجانسة (مؤرشفة) ، فيمدونة True Blue على موقع Oracle
  10. "Lispy Elixir" . 8thlight.com . لغة Elixir، ظاهريًا، ليست متجانسة. ومع ذلك، فإن تركيبها الظاهري ليس سوى واجهة لبنية متجانسة كامنة.
  11. "لماذا أنشأنا جوليا" . julialang.org . نريد لغة متجانسة، مع وحدات ماكرو حقيقية مثل لغة ليسب، ولكن مع رموز رياضية واضحة ومألوفة مثل لغة ماتلاب.
  12. "البرمجة الوصفية" . docs.julialang.org . مثل لغة ليسب، تمثل جوليا شفرتها الخاصة كهيكل بيانات للغة نفسها.
  13. شابيرو، إيهود ي.؛ ستيرلينغ، ليون (1994). فن لغة برولوج: تقنيات برمجة متقدمة . مطبعة معهد ماساتشوستس للتكنولوجيا. ISBN 0-262-19338-8.
  14. رامزي، س.؛ بيتليك-زيليج، ب. (2012). "تقنيات توليد الشفرة لتوافق مجموعات XML" . وقائع مؤتمر العلوم الإنسانية الرقمية dh2012 .
  15. "ملاحظات لخبراء لغات البرمجة" . لغة وولفرام . وولفرام. 2017.