MQL dilinin sözdizimi için dilekler

 

Böyle bir konu oluşturmaya karar verdim çünkü. Gözlemlerime göre, MQL sözdiziminin gelişimi uzun süredir durgundu, son yıllarda dilde hiçbir gelişme görünmüyor. Geliştiricilerin MQL üzerinde daha fazla çalışıp çalışmayacağını bilmiyorum, ancak bazıları kritik olarak gerekli olan birçok eksik özellik var.

Bu başlıkta, ana dilekleri bir araya getirmeye karar verdim. Önce listemi vereyim, belki birileri bir şeyler daha ekler. Ve orada, yol boyunca, belki geliştiriciler bağlantı kuracak ve vizyonlarını ifade edecekler, bu harika olurdu.

Bu listeyi önem sırasına göre (gördüğüm kadarıyla) düzenledim ama kişisel önceliklerime göre değil. Onlar. önce dil için en temel ve olmazsa olmazları sıralar. Bir kılavuz olarak, C++ ve C# işlevlerini alıyoruz


1. Türlerle çalışma: typedef , decltype , auto

Bu, genel olarak, temel işlevsellik, en azından ilk iki belirteçtir. Adlandırma ve tür alma işlemleri yalnızca kolaylık sağlamak için değil, aynı zamanda kodun güvenilirliği ve esnekliği için de oluşturulur. Her yerde, farklı yerlerde kullanılan belirli değişken türlerine katı bir şekilde yer verilmişse, türlerden herhangi birini değiştirmeniz gerektiğinde sorunlar başlar.

Buradaki çoğu kişi typedef'e zaten aşinadır, ancak ne yazık ki, bu hala yalnızca işlev işaretçileriyle çalışan bir güdüktür. Decltype konusuna gelince, bilmeyenler için açıklamama izin verin: kendisine iletilen ifadenin türünü argüman olarak döndürür, böylece bazı değişkenlerin veya işlevlerin türlerini diğerlerinin türlerine göre esnek bir şekilde ayarlamanıza izin verir. :

 int a= 100 ;
//...
decltype (a) b= a;

Veya typedef kullanarak:

 typedef int type;
type a= 100 ;
type b = a;
Veya örneğin, uzun ve karmaşık türler söz konusu olduğunda (örneğin, ClassA< ClassB< ClassC,ClassD<ClassE> > >) - o zaman Tanrı bunu bir typedef içine sarmayı emretti

C#'da typedef yerine using kullanılır.

MQL'de bunların hiçbiri yok. Mümkün olan tek şey, problemlerle dolu olan define aracılığıyla türü ayarlamak için bir koltuk değneği seçeneğidir.


2. Ad alanları: ad alanı

Bu konu yakın zamanda tartışıldı. Benim için, neden henüz uygulanmadığı genellikle çok garip, çünkü. bu dilde bir zorunluluktur. Özellikle topluluğun gelişimine yönelik eğilim göz önüne alındığında, kod tabanı kullanımı, grup geliştirme. Bu durumda, isimleri eşleştirme sorunu çok alakalı hale gelir.

Burada bir fonksiyonun içindeki yerel bir değişkenin ismi başka bir dosyada tanımlanan bir tipin ismi ile eşleştiğinde bile derleyicinin hata verdiğine dair bir örnek verdiler. Çirkinlik.

Ve genel olarak, her şeyin tek bir alanda tek bir yığına atılması yanlıştır.


3. Döküm operatörü yazın veya daha doğrusu sınıfta aşırı yüklenme olasılığı. Onsuz, kullanıcı tanımlı türler doğal olarak yetersizdir ve esneklik büyük ölçüde azalır.
Diyelim ki zamanı tutan bir DATETIME yapısı yaptınız ve bunun bir datetime olarak da kullanılabilmesini, bunu datetime alan tüm fonksiyonlara geçirmesini ve datetime ifadelerinde kullanmasını istiyorsunuz.
Genellikle bu basitçe yapılır: yapıcıyı ve döküm operatörünü uygun tiple aşırı yükleriz ve yapımızın bu tiple tam uyumluluğunu elde ederiz:

 struct DATETIME
{
  DATETIME( datetime time) { ... }
   operator datetime () const { return ...; }
};

Ancak MQL'de bunun yerine ayrı bir to_datetime() yöntemi oluşturmanız ve onu her yerde çağırmanız gerekir. Veya DATETIME & tipi için hedef işlevleri aşırı yükleyin, bu da konfor ve esneklik katmaz.


4. Çoklu arayüzler . Eh, bu konuda zaten bir çok söylenti ve konuşma yapıldı (üç yıl önce servis masasında çalışmaların devam ettiğini yazdıklarını hatırlıyorum), ancak süreç bir şekilde uzadı ... Eğer devam ediyorsa.



5. Yapılar için arayüz desteği . Bu, OOP ile birleşik çalışma için gereklidir. Şimdi sık sık koltuk değneklerini çitle çevirmek gerekiyor.

Bu işlevsellik iki şekilde uygulanabilir: ya C#'da olduğu gibi - paketleme/paket açma (kutulama) yoluyla ya da daha esnek bir seçenek - yapı için, yapının içinde bulunduğu dinamik nesnenin tanımlayıcısına bağlı dinamik bir tanımlayıcı oluşturarak. konumlandırılmış - daha verimli olurdu, artı aslında, yapılara ve diğer veri türlerine yönelik işaretçiler oluşturmak mümkün olurdu, bu da esnekliği büyük ölçüde artıracaktır.


6. Küçük yapıları (yukarıdaki örnekte verilen DATETIME ile aynı) geçirirken alakalı olan, yapıları değere göre iletme yeteneği , yapı yapıcısı böyle bir türü destekliyorsa, bir türden diğerine anında esnek dönüşümlere izin verir. Referansla geçerken böyle bir esneklik yoktur. Yapılar için arayüzler uygulansa da, bu daha az alakalı hale gelecektir.


7. Şablonun sayısal parametrelerini ayarlama yeteneği:

 template < int N>
struct A
{
   char a[N];
};

A< 100 > a;
template < int N>
void f( int &arr[][N]) {  }

void start()
{
   int a[][ 5 ];
  f(a);
}

İkinci örneğe gelince, MQL4'te onsuz yapabilirsiniz, çünkü orada işlevler herhangi bir boyuttaki dizileri kabul eder. Ancak MQL5'te, çok boyutlu dizilerle her şey çok daha karmaşıktır.


8. Şablonların uzmanlaşması (belirli türler için ayrı uygulama).

Fonksiyonlu örnek:
 struct A
{
   double _value;
 
   template < typename T>
   T      ToType() { return (T) round (_value); }  
   template <>
   double ToType() { return _value; }
   template <>
   float   ToType() { return ( float )_value; }
   template <>
   string ToType() { return DoubleToString (_value, 2 ); }
};

void f(A& a) { Print (a.ToType< string >()); }

Bir sınıfla örnek:
 template < typename T>
struct CArrayBase     // Базовый класс массива
{
  T _data[];
   int Size()          { return ArraySize (_data); }
  T operator []( int i) { return _data[i]; }
};

template < typename T>
struct CArray : CArrayBase<T> { };   // Основной класс массива

template <>
struct CArray< double > : CArrayBase< double >   // Специализация класса для массива double
{
   double Sum() { double sum= 0 ;   for ( int i= 0 ; i<Size(); i++) sum+=_data[i];   return sum; } 
}; 

template < typename T>
struct CArray<T*> : CArrayBase<T*>   // Специализация класса для массива указателей
{
   void DeleteObjects() { for ( int i= 0 ; i<Size(); i++) { delete _data[i]; _data[i]= NULL ; } }    
};

void start()
{
  CArray< double > arr1;
  arr1.Sum();  

   class A { };
  
  CArray<A*> arr2;
  arr2.DeleteObjects();
}



Peki, küçük şeylerde:


9. Bir dizi işaretçiyi (açıkça veya dolaylı olarak) bir dizi temel işaretçiye aktarabilme . Daha eski yapılarda bu işe yaradı ve çok uygundu:

 interface I { };
class A : I { };

void f(I* &Array[]) {  }

void Main(A* &array[]) { f(array); }

Şimdi diziyi yeni bir diziye yeniden kopyalamanız ve ardından geri almanız gerekiyor, bu da para kaybı.

10. Bir nesne referansı yayınlama: (type&)object

Verilen nesneleri fonksiyona geçirebilmek için bu gereklidir. Aşağıdaki örnekte, B sınıfı bir nesneyi temel A sınıfı bir nesne olarak bir dosyaya yazmak istiyorsunuz, ancak bu şimdi mümkün değil, bir ara fonksiyon oluşturmanız veya nesneyi yeni bir nesneye kopyalamanız gerekiyor.

 struct A { int a; };

struct B : A { int b; };

B b;

void main()
{
   int h= FileOpen ( "MyFile" , FILE_BIN | FILE_WRITE );
   FileWriteStruct (h, (A&)b);   // '&' - unexpected token
   FileClose (h); 
}


11. Dizilerin ve yapıların yalnızca sabitlerle değil, herhangi bir ifadeyle başlatılması. Bu, bu gibi durumlarda kodu büyük ölçüde kısaltır ve basitleştirir:

 void f( int a, int b, int c, int d, int e, int f)
{
   int arr[]= { a, b, c, d, e, f };
 //......
}


12. İşaretçiyi açıkça sayısal bir değere dönüştürme yeteneği.

Bu, bir ikili arama yoluyla veya bir karma tablo oluşturarak istenen işaretçiyi hızlı bir şekilde bulmak için işaretçi dizilerini değerlerine göre sıralamanıza olanak tanır. Artık sadece bir metin formuna dönüştürerek sayısal bir değer elde etmek mümkün, bu da tüm fikri öldürüyor.

13. Şablon varsayılanlarını ayarlama

 template < typename T>
struct DefaultConstructor { static T* New() { return new T; } };

template < typename T, typename TConstructor=DefaultConstructor<T>>
struct A
{
  T* data;
  A() { data= TConstructor::New(); }
 ~A() { delete data; }
};

class B { };

A<B> a;
 

Benim düşünceme göre, tüm bunlar çok az sayıda insan için gereklidir.

Codebase'deki koda bakılırsa, OOP kullanıcılarının %95'i son derece kötü kullanıyor. Ve kalan% 5'ten çoğu - tüm bu olasılıklar çok az işe yarar. Tabii ki hoşlar ve hatta faydalı bile olabilirler ama bence tüm bu iyileştirmelere çok da gerek yok.

 
Georgiy Merts :

Benim düşünceme göre, tüm bunlar çok az sayıda insan için gereklidir.

Codebase'deki koda bakılırsa, OOP kullanıcılarının %95'i son derece kötü kullanıyor. Ve kalan% 5'ten çoğu - tüm bu olasılıklar çok az işe yarar. Tabii ki hoşlar ve hatta faydalı bile olabilirler ama bence tüm bu iyileştirmelere çok da gerek yok.

Evet, anlıyorum, ancak kod tabanına ek olarak, Serbest ve Market de var ve MQ'nun ürünlerin kalitesiyle ilgilenmesi gereken yer burası. Ve dilin kalitesi bir şekilde geliştirme ve hata ayıklamanın kalitesini ve hızını etkiler.

Ve yüzdeler hakkında böyle konuşuyorsanız, o zaman neden MQL5 yaratıldı? Hala ne OOP'ye ne de başka bir şeye ihtiyaç duyulan eski hardcore MQL4'te oturuyorlardı ... Kullanıcıların %99'u her şeyden memnundu)

Belki de normal programcılar tam olarak MQL'ye gitmezler çünkü bu hala daha düşük bir dildir.

 
Alexey Navoykov :

Böyle bir konu oluşturmaya karar verdim çünkü. Gözlemlerime göre, MQL sözdiziminin gelişimi uzun süredir durgundu, son yıllarda dilde hiçbir gelişme görünmüyor. Geliştiricilerin MQL üzerinde daha fazla çalışıp çalışmayacağını bilmiyorum, ancak bazıları kritik olarak gerekli olan birçok eksik özellik var.

Bu başlıkta, ana dilekleri bir araya getirmeye karar verdim. Önce listemi vereyim, belki birileri bir şeyler daha ekler. Ve orada, yol boyunca, belki geliştiriciler bağlantı kuracak ve vizyonlarını ifade edecekler, bu harika olurdu.

Bu listeyi önem sırasına göre (gördüğüm kadarıyla) düzenledim ama kişisel önceliklerime göre değil. Onlar. önce dil için en temel ve olmazsa olmazları sıralar. Bir kılavuz olarak, C++ ve C# işlevlerini alıyoruz


1. Türlerle çalışma: typedef , decltype , auto

Bu, genel olarak, temel işlevsellik, en azından ilk iki belirteçtir. Adlandırma ve tür alma işlemleri yalnızca kolaylık sağlamak için değil, aynı zamanda kodun güvenilirliği ve esnekliği için de oluşturulur. Her yerde, farklı yerlerde kullanılan belirli değişken türlerine katı bir şekilde yer verilmişse, türlerden herhangi birini değiştirmeniz gerektiğinde sorunlar başlar.

Buradaki çoğu kişi typedef'e zaten aşinadır, ancak ne yazık ki, bu hala yalnızca işlev işaretçileriyle çalışan bir güdüktür. Decltype konusuna gelince, bilmeyenler için açıklamama izin verin: kendisine iletilen ifadenin türünü argüman olarak döndürür, böylece bazı değişkenlerin veya işlevlerin türlerini diğerlerinin türlerine göre esnek bir şekilde ayarlamanıza izin verir. :

Veya typedef kullanarak:

Veya örneğin, uzun ve karmaşık türler söz konusu olduğunda (örneğin, ClassA< ClassB< ClassC,ClassD<ClassE> > >) - o zaman Tanrı bunu bir typedef içine sarmayı emretti

C#'da typedef yerine using kullanılır.

MQL'de bunların hiçbiri yok. Mümkün olan tek şey, problemlerle dolu olan define aracılığıyla türü ayarlamak için bir koltuk değneği seçeneğidir.


2. Ad alanları: ad alanı

Bu konu yakın zamanda tartışıldı. Benim için, neden henüz uygulanmadığı genellikle çok garip, çünkü. bu dilde bir zorunluluktur. Özellikle topluluğun gelişimine yönelik eğilim, kod tabanı kullanımı, grup geliştirme göz önüne alındığında. Bu durumda, isimleri eşleştirme sorunu çok alakalı hale gelir.

Burada bir fonksiyonun içindeki yerel bir değişkenin ismi başka bir dosyada tanımlanan bir tipin ismi ile eşleştiğinde bile derleyicinin hata verdiğine dair bir örnek verdiler. Çirkinlik.

Ve genel olarak, her şeyin tek bir alanda tek bir yığına atılması yanlıştır.


3. Döküm operatörü yazın veya daha doğrusu sınıfta aşırı yüklenme olasılığı. Onsuz, kullanıcı tanımlı türler doğal olarak yetersizdir ve esneklik büyük ölçüde azalır.
Diyelim ki zamanı tutan bir DATETIME yapısı yaptınız ve bunun bir datetime olarak da kullanılabilmesini, bunu datetime alan tüm fonksiyonlara geçirmesini ve datetime ifadelerinde kullanmasını istiyorsunuz.
Genellikle bu basitçe yapılır: yapıcıyı ve döküm operatörünü uygun tiple aşırı yükleriz ve yapımızın bu tiple tam uyumluluğunu elde ederiz:

Ancak MQL'de bunun yerine ayrı bir to_datetime() yöntemi oluşturmanız ve onu her yerde çağırmanız gerekir. Veya DATETIME & tipi için hedef işlevleri aşırı yükleyin, bu da konfor ve esneklik katmaz.


4. Çoklu arayüzler . Eh, bu konuda zaten bir çok söylenti ve konuşma yapıldı (üç yıl önce servis masasında çalışmaların devam ettiğini yazdıklarını hatırlıyorum), ancak süreç bir şekilde uzadı ... Eğer devam ediyorsa.



5. Yapılar için arayüz desteği . Bu, OOP ile birleşik çalışma için gereklidir. Şimdi sık sık koltuk değneklerini çitle çevirmek gerekiyor.

Bu işlevsellik iki şekilde uygulanabilir: ya C#'da olduğu gibi - paketleme/paket açma (kutulama) yoluyla ya da daha esnek bir seçenek - yapı için, yapının içinde bulunduğu dinamik nesnenin tanımlayıcısına bağlı dinamik bir tanımlayıcı oluşturarak. konumlandırılmış - daha verimli olurdu, artı aslında, yapılara ve diğer veri türlerine yönelik işaretçiler oluşturmak mümkün olurdu, bu da esnekliği büyük ölçüde artıracaktır.


6. Küçük yapıları (yukarıdaki örnekte verilen DATETIME ile aynı) geçirirken alakalı olan, yapı yapıcısı böyle bir türü destekliyorsa, bir türden diğerine anında esnek dönüşümlere izin verecek şekilde yapıları değere göre iletme yeteneği . Referansla geçerken böyle bir esneklik yoktur. Yapılar için arayüzler uygulansa da, bu daha az alakalı hale gelecektir.


7. Şablonun sayısal parametrelerini ayarlama yeteneği:

İkinci örneğe gelince, MQL4'te onsuz yapabilirsiniz, çünkü orada işlevler herhangi bir boyuttaki dizileri kabul eder. Ancak MQL5'te, çok boyutlu dizilerle her şey çok daha karmaşıktır.


8. Şablonların uzmanlaşması (belirli türler için ayrı uygulama).

Fonksiyonlu örnek:

Bir sınıfla örnek:



Peki, küçük şeylerde:


9. Bir dizi işaretçiyi (açıkça veya dolaylı olarak) bir dizi temel işaretçiye aktarabilme . Daha eski yapılarda bu işe yaradı ve çok uygundu:

Şimdi diziyi yeni bir diziye yeniden kopyalamanız ve ardından geri almanız gerekiyor, bu da para kaybı.

10. Bir nesne referansı yayınlama: (type&)object

Verilen nesneleri fonksiyona geçirebilmek için bu gereklidir. Aşağıdaki örnekte, B sınıfı bir nesne, temel A sınıfının bir nesnesi olarak bir dosyaya yazılmalıdır, ancak bu şu anda mümkün değildir, bir ara fonksiyon oluşturmak veya nesneyi yeni bir nesneye kopyalamak gereklidir.


11. Dizilerin ve yapıların yalnızca sabitlerle değil, herhangi bir ifadeyle başlatılması. Bu, bu gibi durumlarda kodu büyük ölçüde kısaltır ve basitleştirir:


12. İşaretçiyi açıkça sayısal bir değere dönüştürme yeteneği.

Bu, bir ikili arama yoluyla veya bir karma tablo oluşturarak istenen işaretçiyi hızlı bir şekilde bulmak için işaretçi dizilerini değerlerine göre sıralamanıza olanak tanır. Artık sadece bir metin formuna dönüştürerek sayısal bir değer elde etmek mümkün, bu da tüm fikri öldürüyor.

13. Şablon varsayılanlarını ayarlama

Desteklerim.

 
Georgiy Merts :

Benim düşünceme göre, tüm bunlar çok az sayıda insan için gereklidir.

Codebase'deki koda bakılırsa, OOP kullanıcılarının %95'i son derece kötü kullanıyor. Ve kalan% 5'ten çoğu - tüm bu olasılıklar çok az işe yarar. Tabii ki hoşlar ve hatta faydalı bile olabilirler ama bence tüm bu iyileştirmelere çok da gerek yok.

Bu az sayıdaki kişi herkesin kullanacağı kütüphaneler yazabilir.

 

14. İşlev bağımsız değişkeni sabit bir başvuruysa, geçici bir nesnenin iletilmesine izin verin.

 template < typename Type >
struct complex
{
   Type Re;
   Type Im;
   
   complex() : Re(), Im(){}
   complex( Type re, Type im ) : Re(re), Im(im){}
};

template < typename Type >
void Func( const Type& val )
{
}

void OnStart ()
{
   Func( 5.0 );
   
   complex< double > C( 1.0 , 5.0 );
   Func( C );
   
   Func( complex< double >( 2.0 , 4.0 ) );
}

15. Anahtar kelime arkadaşı.

Bazı sınıflar için, özel üyelere belirli bir sınıfa erişim vermek istiyorum, ancak hepsine değil.

 template < typename Type >
class Matrix;

template < typename Type >
class MatrixData
{
   friend class Matrix< Type >;
   
   int mRefCount;
   int mRows;
   int mColumns;
   
   Type mArray[];
   
public :
   MatrixData();
   MatrixData( int rows, int cols );
};

template < typename Type >
class matrix
{
   MatrixData< Type >* mData;
   
public :
        Matrix();
        Matrix( int rows, int cols );
};

16. Yerleşik türler için açıkça bir kurucu çağırırken bir değişkeni sıfırlayın

Bu, şablonlarda kullanışlı olacaktır.

   double x;         // Не инициализирована
   double y();       // Инициализирована нулём
   double z = 5.0 ;   // Инициализирована 5.0
 
İşaretçileri bile yok) daha temel ne olabilir)
 
Alexey Navoykov :

Böyle bir konu oluşturmaya karar verdim çünkü. Gözlemlerime göre, MQL sözdiziminin gelişimi uzun süredir durgundu, son yıllarda dilde hiçbir gelişme görünmüyor. Geliştiricilerin MQL üzerinde daha fazla çalışıp çalışmayacağını bilmiyorum, ancak bazıları kritik olarak gerekli olan birçok eksik özellik var.

Bu başlıkta, ana dilekleri bir araya getirmeye karar verdim. Önce kendi listemi vereyim, belki birileri bir şeyler daha ekler. Ve orada, yol boyunca, belki geliştiriciler bağlantı kuracak ve vizyonlarını ifade edecekler, bu harika olurdu.

***************

Yasağı bekleyin, kutsal metin eleştirisi kabul edilemez :)

Not: İyileştirmeler oldu, çok küresel değil ama

 
secret :
İşaretçileri bile yok) daha temel ne olabilir)

Olmayacaklar, dil yönetiliyor, GC olmasa da

Sharp'ta da yalnızca güvenli olmayan moddadırlar.

 
Alexey Navoykov :

Evet, anlıyorum, ancak kod tabanına ek olarak, Serbest ve Market de var ve MQ'nun ürünlerin kalitesiyle ilgilenmesi gereken yer burası. Ve dilin kalitesi bir şekilde geliştirme ve hata ayıklamanın kalitesini ve hızını etkiler.

Ve yüzdeler hakkında böyle konuşuyorsanız, o zaman neden MQL5 yaratıldı? Hala ne OOP'ye ne de başka bir şeye ihtiyaç duyulan eski hardcore MQL4'te oturuyorlardı ... Kullanıcıların %99'u her şeyden memnundu)

Belki de normal programcılar MQL'ye tam olarak gitmezler çünkü bu hala daha düşük bir dildir.

Kod tabanı %95 çöp. Uzun süredir MT5'in yeni sürümleri çıkmadı. Renat'ın yeni sürümde küresel bir şey vaat ettiğini hatırlıyorum.

 
Alexey Volchanskiy :

Not: İyileştirmeler oldu, çok küresel değil ama

Peki, tam olarak neydi? Hatırladığım son şey, dinamik nesneleri kopyalamanıza izin veren örtük bir kopyalama operatörüydü, ancak bu önemsiz bir şey, özellikle o zamandan beri çok zaman geçtiğinden.