The nonfix operator in SML - sml

I read the grammar of SML and I found out that beside infix and infixr it also contains nonfix. I tried to find some basic examples but it seems that no one uses it. Also tried to find some previous threads about that operator but there are none.
What is the idea behind nonfix? Why it seems like no one uses it?

nonfix turns an infix operator into a "regular" function on tuples. For example * is a function of type int * int -> int, but can't be called as e.g. * (2,3). If for some reason you wanted to do that, you could do the following:
nonfix *
and then * (2,3) will evaluate to 6.
Unfortunately, as an annoying side effect, you can no longer use 2 * 3.
The reason why it doesn't seem to be heavily used is that if I wanted to use * as a regular function, I could just use op: For example, op * (2,3) evaluates to 6. The annoyance of not being able to later on use * as an infix operator outweighs the advantage of not having to type op.

Related

Evaluating a mathematical expression in C++

In a coding problem I've been working on for some time now, I've come to a step where I have to evaluate a mathematical expression that looks like this :
3 * 2 ^ 3 ^ 2 * 5
and should be evaluated like this :
3 * 2 ^ 3 ^ 2 * 5 = 3 * 2^(3 * 2) * 5 = 3 * 64 * 5 = 960.
In the current form of my implementation, I have two vectors, one contains the operands as integers, while the other one contains the operators as chars.
For the current case, they would be : vector<int> operands = { 3, 2, 3, 2, 5 } and vector<char> operators = { '*', '^', '^', '*' }.
This is just a sample case, the order of operations may differ in the sense that multiplication might not always be the first/last operation to be performed.
I've been stuck at this particular step for a while now, namely evaluating the expression encapsulated by the two vector containers to an integer. I've looked at some mathematical parsers I could find on the web, but I still don't see how to implement a proper evaluation.
A solution would be very much appreciated.
Simply compute the value as you parse the expression, maintaining one variable for the final product and one for the current multiplicand (i.e. the current group of exponents with the corresponding base). Apply each exponential operand sequentially as you see it, thus performing left-associative exponentiation.
As an aside, I wouldn't bother storing the entire expression in some kind of vectorized format; I see no useful reason for doing so.
What you would like is possible with expression templates. They make it possible to evaluate expressions in non-standard order and/or behavior - using them you can also define multiple meaning for the same operator in an expression.

dot operator order of evaluation in c++

I am reading "C++ Primer (5th Edition)" and I've run in something I'm not sure I understand correctly.
The example is pretty much similar to one they gave in the book. Imagine we have some function that returns string (or any class that has non-static members):
string some_function(par1, par2) {
string str;
// some code
return str;
}
I know that you can use the return value of any function to access its members, i.e. something like this is valid:
auto size = some_function(arg1, arg2).size(); // or whatever member of class
However, since the dot operator . and function call operator () have left to right grouping and same precedence, the above expression should be something like this:
(some_function(arg1, arg2)).size()
I suppose I am right so far? The thing I don't understand here is order of evaluation. Since order of evaluation is not specified for . operator, it means that either some_function(arg1, arg2) or size() will be evaluated first. But how can it evaluate size() first if it doesn't know on which object is it working on? This implies that order of evaluation should be fixed from left to right, but it is not. How is this possible?
Another example is something like this:
cin.get().get();
Again, it seems like first cin.get() should be evaluated before second get() since it won't know on which object is it working, but this doesn't seem to be necessarily the case.
Operators of the same precedence are evaluated according to their associativity, which you correctly observe is left-to-right for the operator group containing the function call and element selection operators. Therefore, yes, given the expression
x = foo().bar();
The order of operations is
x = (((foo()).bar)());
accounting for relative precedence and associativity of all operators involved. No one writes code in that manner, though.
Likewise, given
cin.get().get()
the order of operations is
(((cin.get)()).get)()
, so yes, the precedence rules result in the cin.get() sub-expression being evaluated first, yielding the object to which the second . (and thence the rest of the expression) is applied.

What does a *= b + c expand to?

Studying the standard there was no information on how this will expand.
I tried it in visual studio 2008 and it does a = a * (b+c);
Does the standard guarantee that it will always expand to that and not a = a * b + c?
Was this always the way that expression expanded for all c++ standard versions?
Thanks.
Yes it's guaranteed.
a::operator*=(b + c);
EDIT:
Precedence isn't listed in a nice table in the standard, there's a footnote to 5/4 saying:
The precedence of operators is not
directly specified, but it can be
derived from the syntax.
The C++ Reference table is correct though.
Operators like =, *=, etc. have (almost) the lowest precedence (see this reference).
This means that whatever expressions you have on the right side of assignment operator, those expressions will be evaluated first. Then the result of evaluation will be assigned to the variable on the left side of assignment operator (multiplying along the way, in the case of *=).
a *= b + c does not "expand" to anything, *= is not a preprocessor macro.
Yes, modulo some obscure compiler bug the right side has always been evaluated as a unit.
*= is its own operator. It should amount to the same postconditions as writing a = a * (b + c) if the latter is valid but is not guaranteed to use the same path of execution to get there.
The + will have a higher precedence than the *= so it is guaranteed that b+c will be evaluated first, even if a is of a class type and *= is an overload.
*= is a separate operator. For all the built in functions it does the same thing as multiplication and assignment, and if you ever define it for one of your own classes you really SHOULD make it do the same thing, for obvious reasons. However, you wouldn't HAVE to.
That is, *= is its own operator, with its own precedence, and internally it will be represented as "multiplication, then assignment", but at no time is the line ever re-parsed with multiplication and assignment operators in.
Given that, there's two ways that line could possibly be parsed:
As a *= (b+c) (should have the same result as a = a * (b+c) for any sane types)
As (a*=b) + c (which assuming this is a stand-alone statement, will do multiply a by b, assign the result to a. It will then multiply the new value by c, but it will throw the result away)
So you can see, there's no precedence which would make it do "a = (a*b)+c" which is what you feared.
In fact, the second is clearly not very useful, and for this reason, all the assignment and something-assignment operators have lower precedence than arithmetic and other "normal" operations, in fact, lower precedence than anything except ",".
It's easy to check the precedence by googling and finding a table like:
http://www.cppreference.com/wiki/language/operator_precedence
I don't remember all of the details, so it's fine to check if you're not sure between similar operators, but you can do most of it by remembering the general principles like this one.

Can I expand a typedef in SMLNJ?

So I was writing up some code in standard ML, and trying to compile it with smlnj. I got the following error:
Error: operator and operand don't agree [tycon mismatch]
operator domain: unit -> Absyn.fundec
operand: unit
-> (pos * pos) *
((string * int) * (string * int) * Absyn.tp * Absyn.tp
* Absyn.exp)
Now, this looks like it should be a type match based on my cursory inspection of the types. I'm not going to tell you them since I want a general solution, not the bug in my code.
Is it possible to expand both types into the base datatypes so I can figure out how they differ? With all these typedefs floating around things get confusing, and digging through .sml files for all the definitions and writing the expansion on paper seems like a tedious solution.
I would love to say something like:
typeof Absyn.fundec
and figure out what the heck kind of expression might produce a valid fundec.
As Absyn.fundec is not a standard type as int, bool, etc. there must be a datatype or a type declaration which should tell you exactly how the Absyn.fundec type is defined.

Why "**" does not bind more tightly than negation in OCaml?

after this question, I don't know what to think.
In OCaml, if you do something like -1.0**2.0 (because of the typing you need to have float), you obtain 1.00. According to the standard order of operations, the result should be -1 (as in python).
I wasn't able to find the reason or a clear definition of the operator precedence in OCaml...
Is this because of the type system ? or the fact that there's a binding underneath with pow ?
As the very page you quote says, "The order in which the unary operator − (usually read "minus") acts is often problematical." -- it quotes Excel and bc as having the same priority for it as O'CAML, but also says "In written or printed mathematics" it works as in Python. So, essentially, there's no universal consensus on this specific issue.
Operator precedence is syntax-directed in OCaml, which means that the first character of the function identifier (and whether it's unary or binary) determines the operator precedence according to a fixed sequence. Contrast this with languages like Haskell, where the operator precedence can be specified at function definition regardless of which characters are used to form the function identifier.