نيميرل
نيميرل هي لغة برمجة عامة الأغراض وعالية المستوى وذات كتابة ثابتة ، مصممة للمنصات التي تستخدم البنية التحتية للغة المشتركة ( .NET / Mono ). تدعم نيميرل أنماط برمجة متعددة، بما في ذلك البرمجة الوظيفية ، والبرمجة كائنية التوجه ، والبرمجة الموجهة نحو الجوانب ، والبرمجة الانعكاسية ، والبرمجة الإجرائية . تتميز اللغة ببنية بسيطة تشبه لغة C# ونظام برمجة وصفية قوي . في يونيو 2012، وظفت شركة البرمجيات التشيكية JetBrains مطوري نيميرل الأساسيين . ركز الفريق على تطوير نيترا، وهو إطار عمل لتنفيذ لغات البرمجة الحالية والجديدة. [ 2 ] [ 3 ] [ 4 ] يبدو أن جيت برينز قد تخلت عن كل من نيميرل ونيترا أو أوقفت تطويرهما؛ إذ لم تتلق نيترا أي تحديثات من مطوريها الأصليين منذ عام 2017، وتتولى شبكة تطوير البرمجيات الروسية الآن صيانة نيميرل بشكل مستقل. مع ذلك، لم تصدر أي إصدارات رئيسية، ولا يزال التقدم في التطوير بطيئًا. لم تُشر جيت برينز إلى نيميرل أو نيترا منذ عدة سنوات. سميت اللغة على اسم الساحر الأعظم نيميرلي، وهي شخصية في رواية الخيال "ساحر الأرض" للكاتبة أورسولا ك. لو غوين .
سمات
أبرز ما يميز لغة نيميرل هو قدرتها على الجمع بين أساليب البرمجة الكائنية والوظيفية . يمكن هيكلة البرامج باستخدام مفاهيم البرمجة الكائنية مثل الأصناف ومساحات الأسماء، بينما يمكن (اختيارياً) كتابة الدوال بأسلوب البرمجة الوظيفية. ومن الميزات البارزة الأخرى:
- الاستدلال القوي على النوع
- نظام فرعي مرن للبرمجة الوصفية (باستخدام وحدات الماكرو )
- دعم كامل للبرمجة الكائنية التوجه (OOP)، على غرار لغات C# و Java و C++
- دعم كامل للبرمجة الوظيفية، على غرار لغات ML و OCaml و Haskell ، مع هذه الميزات:
- الدوال ذات الرتبة العليا
- مطابقة الأنماط
- الأنواع الجبرية
- الدوال المحلية
- المجموعات والأنواع المجهولة
- تطبيق جزئي للوظائف
The metaprogramming system allows for great compiler extensibility, embedding domain-specific languages, partial evaluation, and aspect-oriented programming, taking a high-level approach to lift as much of the burden as possible from programmers. The language combines all Common Language Infrastructure (CLI) standard features, including parametric polymorphism, lambdas, extension methods etc. Accessing the libraries included in the .NET or Mono platforms is as easy as in C#.
Type inference
defx=1;// intdefmyList=List();// generic List[T], type T is deduced from the usage in the next linemyList.Add(x);// compiler deduces type of T as int making myList type of List[int]Everything is an expression
defx={// similar to x = 3defy=1;defz=2;y+z// this last statement is a block return value};defx=if(DateTime.Now.DayOfWeek==DayOfWeek.Monday)// if, using, try are also expressions"Monday"else"other day";defx=tryint.Parse(someString)catch{|FormatException()=>0};defx=returnBlock:{foreach(iin[1,2,3])when(i>2)returnBlock(true);// exit block (x = true)false// x = false};Tuples
defk=(1,"one");// k : (int * string)def(a,b)=k;// a = 1, b = "one"Pattern matching
دالة النتيجة = مطابقة ( الرقم ) { | 0 => "صفر" | 1 => "واحد" | x عندما x < 0 => "سالب" | _ => "أكثر من واحد" }مطابقة الأنواع مع ربط المتغيرات:
دالة التحقق ( o : كائن ) { مطابقة ( o ) { | i عدد صحيح => "عدد صحيح: $i " | s سلسلة نصية = > " سلسلة نصية: $ ( s.ToUpper ()) " | _ => " كائن من نوع آخر" } }مطابقة أنماط الصفوف:
match ( tuple ) { | ( 42 , _ ) => "42 في الموضع الأول" | ( _ , 42 ) => "42 في الموضع الثاني" | ( x , y ) => $"( $x , $y )" }مطابقة التعبيرات النمطية:
باستخدام Nemerle.Text ؛ regexp match ( str ) { | "a+.*" => printf ( "a\n" ); | @" ( ?<num : int > \d+)-\w+" => printf ( "%d\n" , num + 3 ); | "(?<name>(Ala|Kasia))? ma kota" => match ( name ) { | Some ( n ) => printf ( "%s\n" , n ) | None => printf ( "noname?\n" ) }| _ => printf ( "default\n" ); }الأنواع الوظيفية والوظائف المحلية
باستخدام System.Console ؛ // يمكن وضع الفئات والوحدات (الفئات الثابتة) في مساحات أسماء. دالة next ( x ) { x + 1 } ؛ // يمكن استنتاج نوع وسيط x ووسائط الدالة الأخرى من الاستخدام.def mult ( x , y ) { x * y };def fibonacci ( i ) { | 0 => 0 | 1 => 1 | other => fibonacci ( i - 1 ) + fibonacci ( i - 2 ) };WriteLine ( next ( 9 )); // 10 مشابه لـ "Console.WriteLine(next(9));" WriteLine ( mult ( 2 , 2 )); // 4 WriteLine ( fibonacci ( 10 )); // 55المتغيرات
المتغيرات (التي تسمى أنواع البيانات أو أنواع المجموع في SML و OCaml) هي أشكال للتعبير عن البيانات من عدة أنواع مختلفة:
متغير RgbColor { | أحمر | أصفر | أخضر | مختلف { أحمر : عدد عشري ; أخضر : عدد عشري ; أزرق : عدد عشري ; } }البرمجة الوصفية
يُتيح نظام الماكرو في لغة نيميرل إنشاء وتحليل وتعديل شيفرة البرنامج أثناء عملية الترجمة. ويمكن استخدام الماكرو إما في صورة استدعاء دالة أو كبنية لغوية جديدة. وتُنفَّذ العديد من البنى اللغوية باستخدام الماكرو (مثل: if، وfor، وforeach، وwhile، وusing، إلخ).
مثال على ماكرو " if ":
macro @if ( cond , e1 , e2 ) syntax ( "if" , "(" , cond , ")" , e1 , Optional ( ";" ), "else" , e2 ) { /* <[ ]> يُعرّف منطقة شبه اقتباس، ويُحوّل مُصرّف Nemerle الكود الموجود فيها إلى شجرة بناء جملة مجردة (AST)، وتُشبه هذه التحويلات إلى حد ما عملية تجميع التعبيرات في لغة C# */ <[ match ( $cond : bool ) { | true => $e1 | _ => $e2 } ]> }// استخدام هذا الماكرو في الكود: def max = if ( a > b ) a else b ; // أثناء وقت الترجمة، سيتم تحويل السطر العلوي إلى هذا: def max = match ( a > b ) { | true => a | _ => b }بناء الجملة بدون أقواس
على غرار بناء الجملة بدون أقواس الذي تمت إضافته لاحقًا إلى Scala ، يسمح Nemerle للمبرمج باستخدام بناء جملة حساس للمسافات البيضاء بشكل اختياري بناءً على قاعدة التجاوز ، على غرار Python .
المقطع التالي ذو الأقواس المعقوفة:
باستخدام System.Console ؛[Qux] class FooBar { public static Main (): void { WriteLine ( "Hello" ) }static Foo ( x : int ): void { if ( x == 3 ) { def y = x * 42 ; Foo ( x ) } else { [ x ] .Map ( fun ( x ) { x * 2 }) } }static Bar (): int { def foo = 2 + 7 * 13 ; foo } }يمكن إعادة كتابتها على النحو التالي:
باستخدام System.Console ؛[Qux] \ class FooBar public static Main (): void WriteLine ( "Hello" )دالة ثابتة Foo ( x : int ): void إذا كان ( x == 3 ) دالة y = x * 42 ; Foo ( x ) وإلا [x] . Map ( دالة ( x ) { x * 2 })دالة ثابتة Bar (): int def foo = 2 + 7 * 13 fooوالجدير بالذكر أنه لا يمكن تقسيم التعبيرات أو العبارات البديلة في المطابقات على عدة أسطر دون استخدام الشرطة المائلة العكسية \:
// لن يتم تجميع هذا الكود ...دالة ثابتة Bar (): int def foo = 2 + 7 * 13 foomatch ( s ) | "a" | "aa" => 1 | "b" | "bb" => 2 | _ => 0 // لكن هذا سيؤدي إلى:دالة ثابتة Bar (): int def foo = 2 \ + 7 \ * 13 fooمطابقة ( s ) | "a" \ | "aa" => 1 | "b" \ | "bb" => 2 | _ => 0لتفعيل هذا التركيب، يجب على المستخدم إضافته #pragma indentإلى أعلى الملف أو استخدام خيار المُصرّف -i.
بيئة التطوير المتكاملة
يمكن دمج Nemerle في بيئة التطوير المتكاملة (IDE) Visual Studio 2008. كما أنها تحتوي على بيئة تطوير متكاملة مجانية بالكامل تعتمد على Visual Studio 2008 Shell [ 5 ] (مثل Microsoft Visual Studio Express ) و SharpDevelop ( رابط إلى شفرة المصدر للملحق ).
يمكن أيضًا دمج Nemerle في Visual Studio (حتى عام 2017) باستخدام الإضافات والملحقات. [ 6 ]
أمثلة
مرحبا بالعالم!
يمكن تنفيذ برنامج "Hello World!" التقليدي بطريقة تشبه لغة C#:
class Hello { static Main () : void { System . Console . WriteLine ( "Hello, world!" ); } }أو ببساطة أكثر:
System.Console.WriteLine ( " Hello, world ! " ) ;أمثلة على وحدات الماكرو
تتيح وحدات الماكرو إنشاء شيفرة نمطية مع إضافة فحوصات ثابتة يُجريها المُصرّف. فهي تُقلل من كمية الشيفرة التي يجب كتابتها يدويًا، وتجعل عملية توليد الشيفرة أكثر أمانًا، وتسمح للبرامج بتوليد شيفرة مع فحوصات المُصرّف، مع الحفاظ على حجم الشيفرة المصدرية صغيرًا نسبيًا وسهل القراءة.
تنسيق السلسلة
يُبسّط ماكرو تنسيق السلسلة التعامل مع المتغيرات إلى عمليات معالجة السلاسل باستخدام رمز $:
def s = $"العدد هو $i " ; // أدخل قيمة المتغير i مكان $i def s = $" $x + $y = $ ( x + y ) " ; // يمكن استخدام $(...) لإجراء العمليات الحسابية أو الوصول إلى الأعضاءتوليد الكود التصريحي
تُعدّ كلٌّ من StructuralEquality و Memoize و json و with وحدات ماكرو تُولّد شيفرةً برمجيةً أثناء عملية الترجمة. ورغم أن بعضها ( مثل StructuralEquality و Memoize ) قد يبدو كسمات C#، إلا أنه أثناء الترجمة، يقوم المُترجم بفحصها وتحويلها إلى شيفرة برمجية مناسبة باستخدام منطق مُحدّد مسبقًا بواسطة وحدات الماكرو الخاصة بها.
[StructuralEquality] // تنفيذ واجهة IEquatable[Sample] في .Net باستخدام مقارنة العناصر. class Sample { [Memoize] // حفظ نتيجة التقييم الأول public static SomeLongEvaluations () : int { MathLib . CalculateNthPrime ( 10000000 ) }[DependencyProperty] // خاصية التبعية في WPF public DependencyPropertySample { get ; set ; } public static Main () : void { /* يُنشئ ماكرو بناء الجملة "json" الكود التالي: JObject.Object([("a", JValue.Number(SomeLongEvaluations())), ("b", JValue.Number(SomeLongEvaluations() + 1))]) */ def jObject = json { a : SomeLongEvaluations (); b : ( SomeLongEvaluations () + 1 )} // ماكرو تهيئة الكائن "<-" هو تطوير لتهيئة الكائن باستخدام الأقواس المعقوفة في C# def k = Diagnostics . Process () <- { StartInfo <- // يمكن تهيئة خصائص الكائنات الداخلية بدون استدعاء الدالة البانية { FileName = "calc.exe" ; UseShellExecute = true ; } Exited += () => WriteLine ( "تم الحساب" ); // الأحداث والمندوبون }ReadLine (); } }إمكانية الوصول إلى قاعدة البيانات
باستخدام وحدات ماكرو Nemerle للغة SQL، يمكنك كتابة ما يلي:
ExecuteReaderLoop ( "SELECT firstname, lastname FROM employee WHERE firstname = $myparm" , dbcon , { WriteLine ( $"Name: $firstname $lastname " ) });بدلاً من
string sql = "SELECT firstname, lastname FROM employee WHERE firstname = :a" ; using ( NpgsqlCommand dbcmd = new NpgsqlCommand ( sql , dbcon , dbtran )) { dbcmd . Parameters . Add ( "a" , myparm );باستخدام ( NpgsqlReader reader = dbcmd.ExecuteReader () ) { بينما ( reader.Read ( ) ) { var firstname = reader.GetString ( 0 ) ; var lastname = reader.GetString ( 1 ) ; Console.WriteLine ( " الاسم : {0} {1} " , firstname , lastname ) } } }وهذا لا يقتصر على إخفاء بعض العمليات في مكتبة، بل يشمل عملاً إضافياً يقوم به المُصرّف لفهم سلسلة الاستعلام، والمتغيرات المستخدمة فيها، والأعمدة المُسترجعة من قاعدة البيانات. سيُنتج ماكرو ExecuteReaderLoop رمزاً يُعادل تقريباً ما ستكتبه يدوياً. علاوة على ذلك، يتصل بقاعدة البيانات أثناء عملية التجميع للتحقق من صحة استعلام SQL الخاص بك.
تراكيب لغوية جديدة
باستخدام وحدات ماكرو Nemerle، يمكنك أيضًا إدخال بعض الصيغ الجديدة إلى اللغة:
macro ReverseFor ( i , begin , body ) syntax ( "ford" , "(" , i , ";" , begin , ")" , body ) { <[ for ( $i = $begin ; $i >= 0 ; $i --) $body ]> }يُعرّف هذا الأمر ماكرو يُقدّم صيغة (EXPR ; EXPR) EXPR ويمكن استخدامه مثل
ford (i ; n) print (i);
نيميرل مع ASP.NET
يمكن تضمين Nemerle مباشرة في ASP.NET :
<%@ Page Language = "Nemerle" %> <script runat= "server" >Page_Load ( _ : object , _ : EventArgs ) : void { Message . Text = $"آخر مرة قمت فيها بالوصول إلى هذه الصفحة كانت في: $(DateTime.Now)" ; }EnterBtn_Click ( _ : object , _ : EventArgs ) : void { Message . Text = $"مرحباً $(Name.Text)، أهلاً بك في ASP.NET!" ; }</script><html> <body> <form runat= "server" > الرجاء إدخال اسمك : <asp:TextBox ID= "Name" runat= "server" /> <asp:Button OnClick= "EnterBtn_Click" Text= "Enter" runat= "server" /><p><asp:Label ID= "Message" runat= "server" /></p> </form> </body> </html>...أو يتم تخزينها في ملف منفصل وإدخالها بسطر واحد:
<%@ Page Language = "Nemerle" Src = "test.n" Inherits = "Test" %>استدعاء بينك
يمكن لـ Nemerle الاستفادة من مكتبات النظام الأساسية. يتشابه بناء الجملة إلى حد كبير مع لغة C# ولغات .NET الأخرى. إليك أبسط مثال:
باستخدام System ؛ باستخدام System.Runtime.InteropServices ؛class PlatformInvokeTest { [DllImport("msvcrt.dll")] public extern static puts ( c : string ) : int ;[DllImport("msvcrt.dll")] internal extern static _flushall () : int ;public static Main () : void { _ = puts ( "Test" ); _ = _flushall (); } }مراجع
- ↑ نيميرل 1.2.507.0
- ↑ "تويتر / orangy: لقد قررنا إحضار نيميرلي" . Twitter.com . تم الاسترجاع في 2013-09-05 .
- ↑ "مدونة أدوات JetBrains .NET » JetBrains و Nemerle" . Blogs.jetbrains.com. 27-06-2012 . تم الاطلاع عليه بتاريخ 05-09-2013 .
- ^ "جوجل ديونشيجروبين" . تم الاسترجاع 2013/09/05 .
- ↑ يمكن تثبيت برنامج تثبيت Nemerle Studio Microsoft Setup Installer بعد تثبيت Visual Studio Shell 2008 Isolated
- ↑ إضافة Visual Studio 2010
للمزيد من القراءة
- منشورات عن نيميرلي في مجلة RSDN، وهي مجلة العلوم الرسمية الروسية
- موسكال، ميخال (27 يونيو 2005). "استدلال النوع مع التأجيل" (ملف PDF) . معهد علوم الحاسوب، جامعة فروتسواف.
{{cite journal}}يتطلب الاستشهاد بالمجلة ( مساعدة )|journal= - عرض تقديمي بعنوان "نيميرلي جديرة بالذكر" من إعداد دينيس ريستسوف
- مقال بعنوان "لغات غير تقليدية لأجهزة حاسوب عملاقة غير تقليدية" بقلم أندريه أدينيتز
روابط خارجية
- لغات البرمجة
- لغات البرمجة الإجرائية
- لغات برمجة .NET
- لغات البرمجة الكائنية التوجه
- لغات البرمجة التي تم إنشاؤها في عام 2003
- برنامج 2003
- لغات البرمجة عالية المستوى
- البرمجة الموجهة نحو الجوانب
- اللغات الوظيفية
- لغات البرمجة ذات الكتابة الثابتة
- لغات برمجة ذات بنية قابلة للتوسيع
