everyone, I'm trying to understand how exceptions work in ML, but I have strange error, and I can't figure out what is wrong:
exception Factorial
fun checked_factorial n =
if n < 0 then
raise Factorial
else n;
fun factorial_driver () =
checked_factorial(~4)
handle
Factorial => print "Out of range.";
what may be wrong? thanks in advance for any help.
You need to make sure that factorial_driver has a consistent type. The non-exceptional case returns int, so ML infers the function to be of type unit -> int, but the exceptional case (that is, the print expression) returns unit, not int.
Generally, you basically need to return a value of the same type in all cases.
Related
I've been using signed long longs and have had weird issues with it - i.e. inconsistent behavior. I.e.
long long i;
printf("%d", i);
This tends to print values which have no relevance to the actual value of i (this also occured with cout).
It also has random behavior with %, i.e.
if(i % x == 0)
//some code
This would sometimes run i.e. if i = 15 and x = 5 it just wouldn't return true and therefore the if statement would not run the code.
It would tend to return true on x = 7 for some reason.
I believe that it may be a fault with the compiler which I believe was just the g++ compiler (it was at a competition).
Any ways to mitigate this or why it was doing this would be greatly appreciated.
To print the various integer types using printf-style syntax requires horrible syntax - I suggest using the C++ type-safe iostreams instead.
I was wondering if there was any significance in a part of a code I am seeing that involves
return (num!=0);
where num is an int. And this is the return statement of a boolean function that wants to return TRUE if num != 0, and false if num = 0.
I am not sure if there is an hidden significance to this, but I am not seeing why they cannot just simply write:
return num;
Here is the code I saw:
bool SemClass::cut(int &a, int &b, int &c)
{
int num = 0;
check(a, num);
check(b, num );
check(c, num);
return (num != 0);
}
The value 0 for integral, floating-point, and unscoped enumeration and the null pointer and the null pointer-to-member values become false when returned as a boolean by implicit conversion. Other values such as 1, 2, 3, 4 etc. map to true. This convention was established in original C, via its flow control statements; C didn't have a boolean type at the time.
Implicit conversions: en.cppreference.com/w/cpp/language/implicit_cast
In this case, in C++, writing num and num!=0 are both fine. However, num!=0 might make it more obvious that the method is returning a boolean. Technically, only an integer of value 0 would equate to a boolean false, while all other values would equate to a boolean true. By writing num!=0, It is made explicit that the method would return true if num is not equivalent to 0 and false if it is.
Good practice dictates that if it's a genuine truth value, then you should use a boolean as it makes it very clear to the caller what will be returned. When returning an integer, it could be seen as a code/enum type value.
Therefore, num!= is preferred to num in this case. The brackets are not required however. Some compilers will also issue a warning if you return an integer when the method is supposed to return a boolean.
The author may have written return num, the compiler would generate the exact same binary. Here, the author tries to be explicit and to make as easy as possible to the reader to guess what the function returns.
When a quick reader sees return num knowing that num is an int and the current function returns a bool, (s)he needs to stop for a fraction of a second to a few seconds (depending on its concentration and ease regarding C++) to remember that an integer is implicitly convertible to a boolean with the mapping 0 -> false, anything else -> true. So, why not write that down?
When the quick reader sees return num!=0, (s)he guesses that the current function returns a boolean (it could be otherwise, but it would be suspicious) and comprehend easily what the return value means.
As a rule of thumb, I'd advise to pick the more explicit writing when it does not hurt the reading and when it takes only a few more (or less) characters. Don't forget that you do not write code for the compiler, you write code for the dozens of other developers who works or will work with you(r code). C++ may be less common in 20 years, it would be great if your program could be easily understood not only by gurus but by everyone (I'm generalizing there, not only talking about the implicit boolean conversion).
The author is being (excessively) careful on two counts:
The parentheses are redundant.
Any numeric type in C++ has an implicit conversion to bool: if the number compares to zero then it's false, else it's true.
Personally I prefer the naked return num; as I find that clearer.
(Note that in C, the relational operators return the int types 1 and 0, rather than true and false).
I am aware of two techniques for flipping a bool:
x = !x
and
x ^= 1
I prefer the second, in the same way that I prefer x++ over x+=1 over x=x+1.
But are they guaranteed to produce the same Assembly code?
And if not, is there some rationale to favour one over the other?
There are never any guarantees about same assembly code. Yes, given bool x, they both do exactly the same thing. Yes, that implies they are likely to be the same.
It is a common fallacy that writing expressions in an unusual way might make them faster. Avoid working with anyone who makes habits based on such ideas.
x = ! x is clearer because ! is defined in terms of Boolean values.
I prefer the second, in the same way that I prefer x++ over x+=1 over x=x+1.
Please prefer the first. It is expected and easily understood by most programmers. The second form, only works for values 0 and 1 in integer's case.
But are they guaranteed to produce the same Assembly code?
No.
And if not, is there some rationale to favour one over the other?
Decreasing the ratio of "wtf/loc" of you code (i.e. how many times would another developer look at your code and say "WTF?!?", over every n lines of code).
Edit: Either way, you will probably never see a real-world example of an application made faster by replacing one expression with the other. It is a matter of style, not a matter of performance.
The second expression is simply a source of difficulty found bugs. For example you may think that some expression has type bool while its actual type due to the integer promotion or usual arithmetic conversion is some integral type.
Consider the following code snippet
unsigned int x = 3;
x ^= 1;
std::cout << x << std::endl;
if ( x == false ) std::cout << "All is O'k\n";
else std::cout << "Oops. Something is wrong!\n";
x = 3;
x = !x;
std::cout << x << std::endl;
if ( x == false ) std::cout << "All is O'k\n";
else std::cout << "Oops. Something is wrong!\n";
So using expression x ^= 1; to flip a boolean value can only confuse readers of the code.
So I would prefer to use x = !x; instead of x ^= 1;
Do not forget about the principle KISS: Keep It Simple Stupid.:)
Though for example in C the result of operator ! has type int nevertheless the value of the operation is either 0 or 1.
From the C Standard
5 The result of the logical negation operator ! is 0 if the value of
its operand compares unequal to 0, 1 if the value of its operand
compares equal to 0.
So for both languages there is a guarantee that the result will be exactly either 0 or 1 for any source value.
!x and x^1 are clearly different operations.
The former is a logical negation, returning a 0/1 value. It makes sense to use it on bools.
The latter is a bitwise exclusive or, returning any possible value. It shouldn't be used on a bool. (For xoring bools, prefer the inequality comparison !=). It is also less efficient in unoptimized code as it invoves and extra operand (1).
K&R forgot to provide a !! operator, that you would have loved, and possibly ~~.
It seems like defining types in SML isnt that helpful:
type point = int * int
val origin : point = (0, 0)
But I could easily just use int * int for typing methods, no? Compared with datatype, with which it seems you can do more interesting things like:
datatype Point = PlanePoint of (int * int) | SpacePoint of (int * int * int)
val origin : Point = SpacePoint(0, 0, 0)
Out of curiosity, what are situations where you really just gotta have a type defined?
The reason is mostly type safety. I will try to explain with a simple example.
Say you have a module that uses 2 types that are represented with real * real
For example, a 2d point like in your example, and a line represented by a slope and a y intercept. Now if you're writing a function like lies_on_line which takes a a point and a line and returns a boolean whether the point lies on the line you have 2 choices for a signature:
val lies_on_line : (int * int) * (int * int) -> bool
Ord
val lies_on_line : point * line -> bool
It's obvious that the 2nd example makes it harder to make mistakes.
Also, while it's more of a benefit for modules, naming a type allows you to change its representation without changing code that uses the type (indirectly through the module).
It makes sense to define aliases for your types in the context of your problem domain. That way you can think in your design in terms of more relevant and meaningful types.
For instance if you are writing a word processor program then you have types like:
type Word = string
type Sentence = Word list
which may make more sense than string and string list.
I'm new to Z3 and searched for the answer to my question here and on Google. Unfortunately, I was not successful.
I'm using the Z3 4.0 C/C++ API. I declared an undefined function d: (Int Int) Int, added some assertions, and computed a model. So far, that works fine.
Now, I want to extract certain values of the function d defined by the model, say d(0,0). The following statement works, but returns an expression rather than the function value, i.e., an integer, of d(0,0).
z3::expr args[] = {c.int_val(0), c.int_val(0)};
z3::expr result = m.eval(d(2, args));
The check
result.is_int();
returns true.
My (hopefully not too stupid) question is how to cast the returned expression to a C/C++ int?
Help is very appreciated. Thank you!
Z3_get_numeral_int is what you're looking for.
Here is an excerpt from the docummentation:
Z3_bool Z3_get_numeral_int(__in Z3_context c, __in Z3_ast v, __out int * i)
Similar to Z3_get_numeral_string, but only succeeds if the value can fit in a
machine int. Return Z3_TRUE if the call succeeded.
You should be careful though. Z3's integer is mathematical integer which can easily exceed the range of 32-bit int. In that sense, using Z3_get_numeral_string and parsing string to big integer is a better option.