آيكون (لغة برمجة)
آيكون هي لغة برمجة عالية المستوى جدًا تتميز بالتنفيذ الموجه بالأهداف والعديد من الإمكانيات لإدارة السلاسل والأنماط النصية. وهي مرتبطة بلغتي سنوبول وSL5، وهي لغات لمعالجة السلاسل. ولغة آيكون ليست لغة كائنية التوجه، لكن تم تطوير امتداد كائني التوجه يُطلق عليه Idol في عام 1996 والذي تحول في آخر الأمر إلى لغة ينيكون.
لغة آيكون مشتقة من فئة ALGOL من لغات البرمجة المهيكلة، ولهذا فهي لها صيغة تشبه لغة سي أو لغة باسكال. وتشبه لغة آيكون إلى حد كبير لغة باسكال، حيث تستخدم صيغة := للتعيينات، والكلمة الأساسية procedure وصيغة مماثلة. ومن ناحية أخرى، تستخدم لغة آيكون الأقواس التي تأخذ شكل حرف C لبناء مجموعات التنفيذ، وتبدأ البرامج بتشغيل إجراء يُطلق عليه "main".
تتشارك لغة آيكون أيضًا بطرق عديدة الميزات مع معظم لغات البرمجة النصية (بالإضافة إلى لغات سنوبول وSL5، والتي أُخذت منها): والمتغيرات ليست هناك حاجة لإظهارها، والأنواع يتم تشكيلها تلقائيًا، والأرقام يمكن تحويلها إلى سلاسل وإعادتها إلى الأرقام تلقائيًا. وهناك ميزة أخرى مشتركة مع العديد من لغات البرمجة النصية، لكن ليست كلها، وهي نقص رمز نهاية السطر؛ ففي لغة آيكون، الأسطر التي لا تنتهي بفاصلة منقوطة تنتهي بفاصلة منقوطة ضمنية.
الإجراءات هي وحدة البناء الأساسية لبرامج آيكون، وعلى الرغم أنها تستخدم تسمية باسكال إلا أنها تعمل بشكل يشبه دوال C إلى حد كبير ويمكن أن تعطي قيم؛ لا توجد الكلمة الأساسية function في لغة آيكون.
codice_1
أحد المفاهيم الأساسية للغة Icon يتمثل في أن هياكل التحكم تستند إلى "نجاح" أو "فشل" التعبيرات، بدلاً من المنطق البولي، كما هو في معظم لغات البرمجة. وفي هذا النموذج، المقارنات البسيطة مثل if a 
if a := read() then write(a)
ستنسخ سطرًا واحدًا من الإدخال القياسي إلى الإخراج القياسي. والمهم في هذا المثال هو أن التعليمة البرمجية ستعمل حتى إذا تسبب الأمر read() في حدوث خطأ، على سبيل المثال، إذا لم يوجد الملف. وفي تلك الحالة ستفشل العبارة codice_2، ولن يُطلب أمر الكتابة.
يسري النجاح والفشل فيما بين الدوال، ما يعني أن أي فشل داخل أي دالة متداخلة سيتسبب في فشل باقي الدوال التي تتداخل معها أيضًا. على سبيل المثال، يمكننا كتابة برنامج لنسخ ملف إدخال كامل إلى إخراج في سطر واحد:
codice_3
عندما يفشل الأمر read()، في نهاية الملف على سبيل المثال، سيسري الفشل في السلسلة وسيفشل الأمر write() أيضًا. وصيغة while، بوصفها هيكل تحكم، تتوقف عند الفشل، أي أنها تتوقف عندما يكون الملف فارغًا. وللمقارنة، ادرس مثالاً مشابهًا مكتوبًا بخوارزمية pseudocode المستندة إلى لغة جافا Java:
codice_4
في هذه الحالة هناك مقارنتان مطلوبتان، واحدة لنهاية الملف (EOF) والأخرى لكافة الأخطاء الأخرى. ونظرًا لأن لغة Java لا تسمح بمقارنة الأخطاء كعناصر منطقية، كما هو الحال في لغة Icon، فيجب استخدام صيغة try/catch المطولة كبديل. كما أن محاولة استخدام الكتل تفرض تأثيرات سلبية على الأداء لمجرد استخدامها، حتى إذا لم تحدث أي أخطاء، وهي تكلفة موزعة تتجنبها لغة Icon.
تشير لغة Icon إلى هذا المفهوم بأنه تنفيذ موجه بالأهداف، حيث يشير إلى الطريقة التي يستمر بها التنفيذ حتى يتحقق هدف ما. وفي المثال السابق، يتمثل الهدف في قراءة الملف بكامله؛ ويتواصل نجاح أمر القراءة طالما أن هناك المزيد من المعلومات المطلوب قراءتها، بينما يفشل عندما لا تكون هناك معلومات. وهكذا تتم برمجة الهدف مباشرة في اللغة، بدلاً من استخدام عبارات لفحص التعليمات البرمجية العائدة أو البنيات المماثلة.
كثيرًا ما تعطي التعبيرات في لغة Icon قيمة واحدة، على سبيل المثال، x <5 ستُقيّم وتنجح مع القيمة 5 أو تفشل. ومع ذلك، يعتمد العديد من الأمثلة التالية على حقيقة أن هناك تعبيرات عديدة لا تعطي نتيجة بالنجاح أو الفشل فورًا، حيث تعطي قيمًا في أثناء ذلك. وهذا يسري على الأمثلة ذات الصيغ every and to؛ every causes to لتواصل إعطاء قيم حتى تفشل.
هذا مفهوم رئيسي في لغة Icon، يُعرف بـ المولدات. وتؤدي المولدات كثير من وظائف الحلقة في اللغة، لكنها تفعل الكثير مباشرة؛ لا يكتب المُبرمج أي حلقة ثم يقوم بسحب القيم ومقارنتها، لكن لغة Icon ستفعل كل هذا لك.
داخل طريقة تعبير لغة Icon، يؤدي تقييم أي تعبير أو دالة إلى تسلسل نتائج. ويحتوي تسلسل النتائج على كل القيم الممكنة التي يمكن توليدها بواسطة التعبير أو الدالة. وعندما ينتهي تسلسل النتائج (على سبيل المثال، لا يوجد مزيد من القيم داخل تسلسل النتائج)، يفشل التعبير أو الدالة. ويتحقق التكرار في تسلسل النتائج إما ضمنيًا عبر التقييم الموجه بالأهداف في Icon أو صراحة عبر العبارة every.
تشتمل لغة Icon على العديد من مُنشئات المولدات. وتسمح الصيغة alternator بتوليد سلسلة من العناصر في تسلسل حتى يفشل أحدها:
codice_5 
يمكنه توليد "1" و"hello" و"5" إذا كان x أقل من 5. على سبيل المثال، يمكن قراءة Alternators كـ "or" في حالات عديدة:
codice_6
سيكتب قيمة y إذا كانت أصغر من x أو 5. وداخليًا تقوم لغة Icon بفحص كل قيمة من اليسار إلى اليمين حتى ينجح أحدها أو تفرغ القائمة وتفشل. وتذكر أنه لن تُطلب الدوال إلا إذا لم تفشل الطلبات بالداخل، ولذلك يمكن تقصير هذا المثال إلى:
codice_7
هناك مولد بسيط آخر وهو codice_8، حيث يقوم بتوليد قوائم من الأعداد الصحيحة؛ وسيقوم codice_9 بعمل ما يبدو عليه تمامًا. وستقوم الصيغة bang بتوليد كل عنصر قائمة؛ وسيقوم codice_10 بإخراج كل رمز في سلسلة في سطر جديد.
لإيضاح قوة هذا المفهوم، انظر في عمليات السلاسل. وتشتمل معظم اللغات على دالة تُعرف بـ codice_11 أو codice_12 والتي تعطي موقع سلسلة داخل أخرى. ادرس:
codice_13
ستعطي هذه التعليمة البرمجية 4، موضع الحالة الأولى للكلمة "the". وللحصول على المثال التالي للكلمة "the" يجب استخدام شكل بديل،
codice_14
الرقم 5 في النهاية يقول أنه ينبغي أن يبدو من الموضع 5 وما بعده. ولاستخراج كل حالات كلمة "the"، يجب استخدام حلقة...
codice_15
في لغة Icon تمثل الدالة find مولدًا، وستعطي المثال التالي من السلسلة عند كل استئناف لها قبل أن تفشل في النهاية بعد تجاوزها نهاية السلسلة. ويمكن كتابة نفس التعليمة البرمجية في لغة Icon:
codice_16
ستعطي الدالة find فهرس المثال التالي لكلمة "the" عند كل استئناف لها بواسطة العبارة every، حيث في النهاية تتجاوز نهاية السلسلة وتفشل. وكما في المثال السابق، سيؤدي هذا إلى فشل الكتابة، وخروج حلقة every (أحادية السطر).
هناك بالطبع أوقات تريد فيها عمدًا البحث عن سلسلة بعد نقطة ما في إدخال، على سبيل المثال، قد تكون تفحص ملفًا نصيًا يحتوي على بيانات في أعمدة متعددة. ويصلح التنفيذ الموجه بالأهداف هنا أيضًا، ويمكن استخدامه بهذه الطريقة:
codice_17
سيظهر الموضع فقط إذا ظهرت كلمة "the" بعد الموضع 5، وإلا فستفشل المقارنة، ممررة ذلك الفشل إلى write() كما سبق. يوجد "حيلة" واحدة صغيرة لهذه التعليمة البرمجية والتي تحتاج لوضعها في الاعتبار: تعطي المقارنات النتيجة اليمنى، لذلك من المهم وضع find على الجانب الأيمن من المقارنة. وإذا كان الرقم 5 على اليمين، فسيُكتب الرقم 5.
تضيف لغة Icon العديد من هياكل التحكم للتكرار الحلقي خلال المولدات. وعامل every يشبه while، ويحدث التكرار الحلقي خلال كل عنصر بواسطة مولد ويخرج عند الفشل:
لماذا استخدام every بدلاً من حلقة while في هذه الحالة؟ لأن while تعيد تقييم النتيجة الأولى، لكن every تقدم كل النتائج. وتقوم صيغة every فعليًا بإدخال قيم في الدالة بطريقة تشبه الكتل في لغة Smalltalk. على سبيل المثال، يمكن إعادة كتابة الحلقة السابقة بهذه الطريقة:
codice_19
بإمكان المستخدمين إنشاء مولدات جديدة بسهولة باستخدام الكلمة الأساسية suspend:
codice_20
هذا المثال يتحلق خلال theString باستخدام find للبحث عن pattern. وعند العثور على واحد، وكان الموضع غريبًا، تعطي الدالة الموقع مع suspend. وبخلاف return، يقوم suspend بكتابة أين يوجد في المولدات الداخلية أيضًا، ما يتيح له معرفة أين تُرك في التكرار التالي.
مع وظائفها التي تشبه البرمجة النصية، تضيف لغة Icon عددًا من الميزات لجعل العمل مع السلاسل أسهل. والأبرز بين هذه الميزات نظام scanning، والذي يكرر طلب الدوال في أي سلسلة:
codice_21
هي شكل قصير من الأمثلة الموضحة في السابق. وفي هذه الحالة يُوضع موضوع الدالة find خارج المعلمات أمام علامة الاستفهام. وتُكتب دوال Icon عمدًا (على عكس تلقائيًا) لمعرفة الموضوع في قوائم المعلمات والسماح بسحبها بهذه الطريقة.
يمكن استخراج السلاسل الفرعية من أي سلسلة باستخدام مواصفات نطاق داخل الأقواس. ويمكن أن تعطي مواصفات النطاق نقطة لرمز مفرد، أو شريحة من السلسلة. ويمكن فهرسة السلاسل من اليمين أو اليسار. ومن المهم ملاحظة أن المواضع داخل أي سلسلة تكون بين الرموز 1A2B3C4 ويمكن تحديدها من اليمين -3A-2B-1C0
على سبيل المثال
codice_22
يوضح المثال الأخير استخدام طول بدلاً من موضع إنهاء
يمكن استخدام مواصفات النصوص المنخفضة كقيمة Lvalue داخل تعبير. وهذا يمكن استخدامه لإدراج سلاسل في سلسلة أخرى أو حذف أجزاء من سلسلة. على سبيل المثال،
codice_23
تسمح أيضًا لغة Icon للمستخدم بإنشاء قوائمه الخاصة بسهولة (أو المصفوفات):
codice_24
ويمكن أن تكون العناصر داخل أي قائمة من أي نوع، وتشمل هياكل أخرى. ولإنشاء قوائم أكبر بسرعة، تشتمل لغة Icon على مولد codice_25؛ codice_26 تولد قائمة تحتوي على 10 من كلمة "word".
ومثل المصفوفات في اللغات الأخرى، تسمح لغة Icon بالبحث عن العناصر حسب الموضع، على سبيل المثال، codice_27.
صيغة bang-syntax، على سبيل المثال، codice_28، ستطبع أربعة أسطر، بكل منها عنصر واحد.
وتشتمل لغة Icon على دوال تشبه التكديس، codice_29 وcodice_30 للسماح لها بتشكيل أساس التكديسات وقوائم الانتظار.
تشتمل لغة Icon أيضًا على وظائف للمجموعات والجداول (تُعرف بـ hashes وassociative arrays وdictionaries، إلخ.):
codice_31
تقوم هذه التعليمة البرمجية بإنشاء جدول سيستخدم الصفر كقيمة افتراضية لأي مفتاح غير معروف. ثم تضيف عنصرين إليه، بالمفاتيح "there" و"here"، والقيم 1 و2.
تتمثل إحدى الميزات القوية للغة Icon في فحص السلاسل. وعامل فحص السلاسل، ? يحفظ بيئة فحص السلاسل الحالية وينشئ بيئة فحص سلاسل جديدة. تتكون بيئة فحص السلاسل من متغيري كلمات أساسية، &subject و&pos. حيث يمثل &subject السلسلة التي يجري فحصها، بينما &pos يمثل المؤشر أو الموضع الحالي داخل سلسلة subject.
على سبيل المثال
codice_33
يمكن استخدام الدوال المضمنة والمعرفة من قبل المستخدم للتحرك داخل السلسلة التي يجري فحصها. والعديد من الدوال المضمنة ستكون افتراضيًا &subject و&pos (على سبيل المثال دالة find). والتعليمات التالية، على سبيل المثال، ستكتب كل "الكلمات" المحددة الفارغة في سلسلة.
codice_34
مثال أكثر تعقيدًا يوضح دمج المولدات وفحص السلاسل داخل اللغة.codice_35
مصطلح expr1 & expr2 & expr3 يعطي قيمة التعبير الأخير
The definitive work is "The Icon Programming Language" (third edition) by Griswold and Griswold, ISBN 1-57398-001-3.
It is out of print but can be downloaded in PDF form.
Icon also has co-expressions, providing non-local exits for program execution. Please see "The Icon Programming language" and also Shamim Mohamed's article "Co-expressions in Icon". (This topic should probably be expanded).