Khaled Alshaya

فض النزاع في أنواع الأنواع!

15 ردود في هذا الموضوع

موضوع جميل جدا - جزاك الله خيرا

لعلى اضيف فكرة الى الموضوع :-

عندما كنت اضع تصميم السوبرنوفا وضعت حل مختلف للمشاكل الناتجة عن نوع المتغير (حرفى - رقمى - إلخ) وهذا الحل هو

(جميع المتغيرات فى السوبرنوفا من نوع واحد فقط هو Data اى بيانات) ويتم اجراء العمليات المختلفة على هذه البيانات حسب السياق

مثلا اذا كان المتغير x يشتمل القيمة 5

والمتغير y يشتمل القيمة 6

فان كل من x و y من النوع Data اى لايتم معاملتهم على انهم ارقام او حروف كما فى معظم لغات البرمجة الاخرى وانما يتم تحديد المعاملة حسب السياق

فاذا تم كتابة [x][y] فان الناتج 56 اى تم الدمج على انهم حروف

واذا تم كتابة [x] + [y] فان الناتج 11 اى تم الجمع على انهم ارقام

والله الموفق

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

ميزة جميلة أخ PWCT Maker :)

كنت سأدخل في موضوع الـ Syntax Sugar و كيفية جعل اللغة Strongly Typed مع إبقاء مرونة الـ Weak Typing و لكن هذا مشوار طويل :P

هناك لغة تسمى Lua فيها ميزة تشبه الموجودة في اللغة التي قمت بصناعتها, و لكن بشكل عام أعتقد أنها ميزة تضيف شيئاً مميزاً لكلا اللغتين. في Lua عملية التحويل نفسها لابد أن تكون صريحة, و لكن اللغة بدلاً أن تضيف دوال لتحويل النصوص إلى أعداد, فإنها جعلتها العملية الرئيسية, و جعلت عملية الـ concatentatoin عملية تتم بغير "+", استخدمت "..", فمثلاً:


1+1
2

1+'1'
2

'1'+'1'
2

'1'..'1'
'11'

'1'..1
'11'

1..1 -- ERROR! because ".." is the concatenation operator!

شكراً على إثراء الموضوع,

تم تعديل بواسطه Khaled.Alshaya
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

مثلا اذا كان المتغير x يشتمل القيمة 5

والمتغير y يشتمل القيمة 6

فان كل من x و y من النوع Data اى لايتم معاملتهم على انهم ارقام او حروف كما فى معظم لغات البرمجة الاخرى وانما يتم تحديد المعاملة حسب السياق

فاذا تم كتابة [x][y] فان الناتج 56 اى تم الدمج على انهم حروف

واذا تم كتابة [x] + [y] فان الناتج 11 اى تم الجمع على انهم ارقام

أعتقد أخى محمود فكرتك مشابهه ل Typed Local Variables

======================================================================

Implicitly Typed Local Variables

In an implicitly typed local variable declaration, the type of the local variable being declared is inferred from the expression used to initialize the variable. When a local variable declaration specifies var as the type and no type named var is in scope, the declaration is an implicitly typed local variable declaration. For example:


var i = 5;
var s = "Hello";
var d = 1.0;
var numbers = new int[] {1, 2, 3};
var orders = new Dictionary<int,Order>();

The implicitly typed local variable declarations above are precisely equivalent to the following explicitly typed declarations:


int i = 5;
string s = "Hello";
double d = 1.0;
int[] numbers = new int[] {1, 2, 3};
Dictionary<int,Order> orders = new Dictionary<int,Order>();

A local variable declarator in an implicitly typed local variable declaration is subject to the following restrictions:

The declarator must include an initializer.

The initializer must be an expression. The initializer cannot be an object or collection initializer (§26.4) by itself, but it can be a new expression that includes an object or collection initializer.

The compile-time type of the initializer expression cannot be the null type.

If the local variable declaration includes multiple declarators, the initializers must all have the same compile-time type.

The following are examples of incorrect implicitly typed local variable declarations:


var x; // Error, no initializer to infer type from
var y = {1, 2, 3}; // Error, collection initializer not permitted
var z = null; // Error, null type not permitted

For reasons of backward compatibility, when a local variable declaration specifies var as the type and a type named var is in scope, the declaration refers to that type; however, a warning is generated to call attention to the ambiguity. Since a type named var violates the established convention of starting type names with an upper case letter, this situation is unlikely to occur

=========================================================================

ولكن كيف التعامل مع الأنواع فى الذاكره فى لغتك هل هى مثل الأستدلال المحلى تتعرف على النوع المناسب وتحدد القيمه فى الذاكره

It is important to understand that the var keyword does not mean “variant” and does not indicate that the variable is loosely typed, or late-bound. It just means that the compiler determines and assigns the most appropriate type.

تم تعديل بواسطه عمرو الصعيدي
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أهلاً أخ عمرو,

لا أعتقد أن الـ Type Inference يشبه المثال الذي ذكره الأخ PWCT Maker, لسبب بسيط, و هو أن الـ Type Inference هو عكس المثال المذكور. في المثال المذكور, قام الأخ بإضافة قليل من الـ Strong Typing على لغة Weak كما في حالة Lua أيضاً, بينما في حالة الـ Type Inference فنحن قمنا بإضافة مرونة "تشبه الموجودة" في الـ Weak Typing و لكن في لغة Strong.

في أي لغة برمجة Strongly Typed, هناك أنواع تمثلها المتغيرات و هناك قيم و هي تعتبر الـ Domain لهذه المتغيرات. لغات البرمجة الـ Strongly Typed تنقسم إلى قسمين رئيسيين. الأول هو أن يكون النوع خاصية من خصائص القيم, بينما المتغيرات نفسها ليس لها أنواع, و لكنها تحمل أنواع القيم التي تحملها. فمثلاً في Python:

x = 5
x = 'Hello Amr'
x = [x for x in range(0, 10)]

لاحظ أن x ليس لها نوع, و قمنا بحمل أكثر من قيمة من أنواع مختلفة في x و لكن اللغة لا تسمح بإجراء عمليات بين أنواع مختلفة.

بينما في لغات أخرى كمعظم اللغات الـ Strongly Typed فإن المتغيرات نفسها يكون لها نوع, و القيم بكل تأكيد لها أنواع و هي أنواع المتغيرات الموجودة في اللغة, فمثلاً في ++C:

int x;
x = 5.0; // ERROR!

كما تلاحظ, x نفسها لها نوع, و ليس القيم التي تحملها فقط.

عندما نذهب مع الأسلوب الثاني في الـ Strong Typing ستقع مشكلة, و هي أن الأنوع أو الـ Type Annotations أو اسم النوع المكتوب أمام المتغير قد يكون معقداً بالنسبة للمستخدم و لكن معرفته أمر عادي جداً بالنسبة للمترجم. فمثلاً في ++C عندما نريد المرور على كل عنصر في set تحتوي على عناصر من نوع set هي الأخرى:

std::set<std::set<int>> my_sets;
...
for(std::set<std::set<int>>::const_iterator i = my_sets.begin();
i != my_sets.end(); ++i)
{ // Do something with my_sets elements! }

لاحظ أننا كتبنا "Annotation" للمتغير i لنوع معقد دون فائدة, كان من الممكن أن يقوم المترجم بمعرفته. فمثلاً:

std::set<std::set<int>> my_sets;
...
for(auto i = my_sets.begin();
i != my_sets.end(); ++i)
{ // Do something with my_sets elements! }

لاحظ كيف جعلت auto الكود مختصراً اكثر! و فوق كل ذلك نحن بمجرد النظر إلى الـ initializer الخاص بـ i عرفنا النوع بشكل عام, و تركنا تحديد النوع بشكل دقيق للمترجم. هذا هو الـ Type Inference باختصار. و هو كما قلنا سابقاً ميزة في اللغات الـ Very Strong و لكن ليس هناك منطق من وجوده أصلاً في لغة كـ Python أو لغة Weak كـ Perl مثلاً.

تحياتي...

تم تعديل بواسطه Khaled.Alshaya
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

شكرا أخى خالد على التوضيح ولكن ممكن شرح أكثر لل WeakTyping

معلومات أكثر عن Type Inference

Type inference, or implicit typing, refers to the ability to deduce automatically the type of a value in a programming language. It is a feature present in some strongly statically typed languages. It is often characteristic of — but not limited to — functional programming languages in general. Some languages that include type inference are: Ada, BitC, Boo, C# 3.0, Cayenne, Clean, Cobra, D, Delphi, Epigram, F#, Google Go, Haskell, haXe, JavaFX Script, ML, Mythryl, Nemerle, OCaml, Oxygene, Scala, and Visual Basic .NET 9.0. This feature is planned for Fortress, C++0x and Perl 6. The ability to infer types automatically makes many programming tasks easier, leaving the programmer free to omit type annotations while maintaining the roughly the same amount of type safety as would be provided with explicit type annotations.

Type inference is the ability to automatically deduce, either partially or fully, the type of an expression at compile time. The compiler is often able to infer the type of a variable or the type signature of a function, without explicit type annotations having been given. In many cases, it is possible to omit type annotations from a program completely if the type inference system is robust enough, or the program or language simple enough.

To obtain the information required to infer the type of an expression, the compiler either gathers this information as an aggregate and subsequent reduction of the type annotations given for its subexpressions, or through an implicit understanding of the type of various atomic values (e.g. true : Bool; 42 : Integer; 3.14159 : Real; etc.). It is through recognition of the eventual reduction of expressions to implicitly typed atomic values that the compiler for a type inferring language is able to compile a program completely without type annotations. In the case of complex forms of higher order programming and polymorphism, it is not always possible for the compiler to infer as much, however, and type annotations are occasionally necessary for disambiguation

.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

موضوع رائع و أتمتى أن نرى مثل هذه المواضيع على صفحات المنتدى.

في C# 4.0 يمكنك الان استخدام الخاصية dynamic في تعريف متغيرات بحيث لا يقوم المترجم بعمل Type checking عليها نهائياً في الCompile Time و هي خاصية رائعة لو كنت ممكن يكتبون أكواد تقوم بتمرير متغيرات بين لغة برمجة Static و أخرى Dynamic فمثلاً في عملي نقوم بتقديم خاصية Scripting للمستخدم بحيث يمكنه كتابة بعض الكود البسيط عن طريق Python و ادراجه في النظام و كانت لدينا دائماً مشكلة في حالة لو كنا نريد من خلال ال#C قراءة object تم انشاءه بالكامل في الPython و ليس له Class تدعمه في ال#C و كنا نقوم بعمليات Reflection كثيرة لمعرفة المتغيرات و الmethods المختلفة داخله, أما الان باستخدام الخاصية dynamic فيمكنك أن تنادي ما تريد في هذا الobject و لن يقوم الCompiler بالاعتراض عليها في وقت الترجمة.

هذا مثال على استخدام الdynamic عموماً

static void Main(string[] args)
{
dynamic d = 10;
int y = d++;
Console.WriteLine(y); //prints 11

d = "string value here";
Console.WriteLine(d.Length); //prints string length 17

d = new ExpandoObject();
d.WhateverProperty = 20;
d.ID = 10;
d.Data = "Data";
Console.WriteLine(d.ID + d.Data); //prints 10Data

d.ID++;

Console.WriteLine(d.ID); //prints 11
}

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أخى تعديل بسيط جدا فى الكود


class Program
{
static void Main(string[] args)
{
dynamic d = 10;
int y = ++d;
Console.WriteLine(y); //prints 11

d = "string value here";
Console.WriteLine(d.Length); //prints string length 17

d = new ExpandoObject();
d.WhateverProperty = 20;
d.ID = 10;
d.Data = "Data";
Console.WriteLine(d.ID + d.Data); //prints 10Data

d.ID++;

Console.WriteLine(d.ID); //prints 11
}

}

فالكود يطبع 10 ليس 11


dynamic d = 10;
int y = d++;
Console.WriteLine(y); //prints 10

تم تعديل بواسطه عمرو الصعيدي
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

شكراً على التعديل, و اسف على الخطأ

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

أخ عمرو,

في الأعلى قسمنا الـ Strongly Typed Languages إلى لغات تهتم بإعطاء نوع للقيم و المتغيرات, و أخرى "تخفف" هذه التشديد بإعطاء نوع للقيم و لكن المتغيرات تعامل على أنها أوعية. عندما نتكلم بشكل نظري, فإن الـ Weak Typing تعني أن القيم لا تنتمي إلى أنواع مختلفة. فمثلاً, في Perl:

print("1"==1);

سوف تخبرك اللغة بأنهما متساويان! هما بالتأكيد متساويان إن كان النوع غير مهم في اللغة أو بمعنى آخر Weak. باختصار, النوع لايدخل في تحديد "شرعية" العملية, لأن اللغة ستوفر طريقة أو حلاً وسطاً لتطبيق العملية على الطرفين.

أخ متميز,

بإذن الله الموضوع القادم سوف يكون عن هذا الأمر :)

تحياتي...

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

السلام عليكم و رحمة الله وبركاته

أخي المتميز ما هو الجديد في الكلمة Dynamic عن تعريف المتغيرات بالطريقة المعتادة.

على حد علمي في الأصدارات السابقة من الـ NET. النوع Object كان يمكن أن يمثل

جميع المتغيرات و أن المتغير من النوع Object كان يمكن أن يتم أسناد أي قيمة

إليه كرقم أو نص أو حتى Object و في الأصدار 6 كان النوع Variant يشبه ذلك

(أعذرنا من طائفة الفيجوالية :) ) أنا أستفسر فقط لأني لست خبير في هذا

المجال و أول مرة أقرأ مثل هذا التصنيف للغات في هذا الموضوع الجميل

جزاك الله خيراً أخي Khaled.Alshaya.

تم تعديل بواسطه COMFORT
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

جزاك الله خيراً أخي عمرو الصعيدي على الرابط موضوع جميل

لكن السؤال بصيغة أخرى ما هو الفرق بين أستخدام معرف بهذا الشكل وبين متغير

آخر معرف على أنه من النوع Object أو Variant مثلاً.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

الفرق شاسع .. استخدام object أو var .. لا تعني أن الـ variable غير معلوم .. بل إن الـ Compiler يعرف الـ data type أثناء الـ compile time

بمعنى:


var x = new List<int> { 1, 2, 3 };

x هنا معروف أنه List في ال compile time ..

أما dynamic لا يتم معرفة الـ type إلا في ال run time ..

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

موضوع ممتاز

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

من فضلك سجل دخول لتتمكن من التعليق

ستتمكن من اضافه تعليقات بعد التسجيل



سجل دخولك الان

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .