A major missing element in the MQL language is a universal None type like in Python. MQL5 has "WRONG_VALUE", but with double, for example, it sets the value to -1.0 which is unacceptable in most cases. It became an obvious issue when I was debugging a substantial project and come to find-out that a double was initialized to DBL_MIN but then later on accidentally compared DBL_MAX. This of course introduced a very difficult to find bug in the code. So I'm curious to how others are implementing safe 'None' value initialization and comparisons. Here's what I came up with, but I can't help but think that there might be a better way???
I sometimes find myself in a similar situation, but it does not happen often (at least, in my experience).
I do not have a custom-built solution for this the same way you did. But I agree, nullable types, or a similar feature, would be nice to have. It can resolve some ambiguity in coding. For example, with SymbolInfoInteger(), I almost always use the second form nowadays (passing a variable by reference). The first form can be unreliable at times with no easy way to confirm if the value you received is the really the requested data or not. I think the same can also be said of other functions, such as ObjectFind(), which can be confusing if you forgot that the return value should be less than zero to confirm that no object was found.
Interesting question.
It seems to work for double but (int)"nan" == 0.
It seems to work for double but (int)"nan" == 0.
My goal with this is to eliminate any possible ambiguity in setting and comparing values of 'None'. I realize I could simply re-define values
#define NONE_INT INT_MAX int a = NONE_INT;
...but I prefer to see a more explicit use...
int a = NONE(int);
Thoughts?
Similar to @Enrico Lambino , I come across this situation sometimes but not really that often.
I basically do a lot of checking of return values on a case-by-case basis.
I do this through unit tests and/or asserts() in my code.
Yes, the asserts() make the code less efficient, but I am willing to do that rather than chase down round pegs in square holes. As with anything, one chooses their battles in life.
#define assert(condition, message, returnVal) \ if(!(condition)) { \ alert(StringFormat("Assertion [%s] failed! %s", #condition, message )); \ return returnVal; \ } #define assertRemove(condition, message, returnVal) \ if(!(condition)) { \ alert(StringFormat("Assertion [%s] failed! %s", #condition, message )); \ ExpertRemove(); \ return returnVal; \ }Oh, and in some cases, I will use a ridiculous value as a return value. Something like 999 when I expect a number between 0 an 10, e.g.
My goal with this is to eliminate any possible ambiguity in setting and comparing values of 'None'. I realize I could simply re-define values
...but I prefer to see a more explicit use...
Thoughts?
Similar to @Enrico Lambino , I come across this situation sometimes but not really that often.
I basically do a lot of checking of return values on a case-by-case basis.
I do this through unit tests and/or asserts() in my code.
Yes, the asserts() make the code less efficient, but I am willing to do that rather than chase down round pegs in square holes. As with anything, one chooses their battles in life.
Oh, and in some cases, I will use a ridiculous value as a return value. Something like 999 when I expect a number between 0 an 10, e.g.This is cool! I don't know why but it never dawned on me to pass entire expressions into the MACRO. I present to you -- MQL's first anonymous functions. ;)
#define lambda(type, var, return_statement) \ class _Lambda{public:static type func(type var){return(type)(return_statement);}}; #define map(lambda_func, array) {\ lambda_func\ for(int i=ArraySize(array)-1; i>=0; --i){\ array[i] = _Lambda::func(array[i]);\ }\ } void OnStart() { int nums[] = {1, 2, 3, 4}; map(lambda(int, x, pow(x, 2)), nums); //square each num in array map(lambda(int, x, x - 5), nums); //subtract 5 from the resulting nums in array ArrayPrint(nums); //-4 -1 4 11 string hellos[] = { "Hello", "World!", "Hello", "World!" }; map(lambda(string, x, x=="Hello"? x+" World!":"Hello "+x), hellos) ArrayPrint(hellos); //"Hello World!" "Hello World!" "Hello World!" "Hello World!" }
This is cool! I don't know why but it never dawned on me to pass entire expressions into the MACRO. I present to you -- MQL's first anonymous functions. ;)
You continue to bridge MQL to python!
Glad my off-topic rambling was helpful. :-D
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
A major missing element in the MQL language is a universal None type like in Python. MQL5 has "WRONG_VALUE", but with double, for example, it sets the value to -1.0 which is unacceptable in most cases. It became an obvious issue when I was debugging a substantial project and come to find-out that a double was initialized to DBL_MIN but then later on accidentally compared DBL_MAX. This of course introduced a very difficult to find bug in the code. So I'm curious to how others are implementing safe 'None' value initialization and comparisons. Here's what I came up with, but I can't help but think that there might be a better way???