I am trying to calculate the expression i and I can't figure out how to print the value as I'm new to f#.
let mutable sqSum = 0.0
let mutable sqrRoot = 0.0
for i in [startNum..endNum] do
for j in [i..(i+k-1)] do
let x = j |> double
sqSum <- x*x
sqrRoot <- sqrt sqSum
if <>sqrRoot % 1.0 > 0.0 then
printfn "%i" i
The specific error message you are seeing should point to the exact location of the problem (at least for the compilers I use). So, specifically, it should be saying the infix operator located where "<>" is, is incorrect, which is true.
In many other languages, we use "!" to say the opposite of a boolean value. In F#, we may often use "<>" as a replacement for "not equal" or "!=". However, in your specific instance, we need to just simply use the keyword "not" and to surround the expression with parantheses (otherwise it will attempt to "not" a float value).
Specifically, you're code should look like this:
if not (sqrRoot % 1.0 > 0.0) then
As an additional note, you might want to fix your indentation as, like Python, indentation is very important in F# as it's not used for readability, but for specifying blocks of code. However, I cannot see all of your code, so it might be fine depending on how it is setup.
Related
I am interested in detecting redundant parentheses in OCaml code. Some ideas I have tried with no results include using regular expressions, comparing reverse code generated from AST. I am lost on how to proceed with this task.
There is a simple solution. Parse the code (using compilerlibs) and then print it back (again using compiler libs) and compare the results. The compilerlibs pretty printer will not put any redundant parentheses. To make the comparison easier, you can remove all spaces, or just count the number of parentheses.
There are less heave and more adhocy approaches, e.g., to catch the common misuse of parentheses:
f(x) instead of f x
(f x) * (f y), instead of f x * f y where * is an arbitrary infix operator.
Finally, the general approach, in case if you need for the student project. Would be to compare operators precedence and mark operators that have higher precedence (bind tighter) but still have parenthesis, e.g., (x * y) + z, here * has higher precedence than + but is still delimited with parentheses.
I'm taking a look to this programming language "Ocaml" and I have some troubles because I read the official ocaml documentation but I don't uderstand how to use :
";" and ";;" and "in" specially inside the definition of functions.
This is my code :
let abs_val value : int -> int =
let abs_ret = ref 0 ;
if value >= 0
then abs_ret := value
else abs_ret := -value ;
let return : int = abs_ret
;;
print_int abs_val -12
Compiled with "ocamlc" it said :
File "first_program.ml", line 7, characters 2-4:
7 | ;;
^^
Error: Syntax error
And it sounds so weird for me because official ocaml's doc says that when function definition ends I must use ";;".
I noticed that after the definition of abs_val VisualStudio Code ,when I go on a newline, put automatically the cursor to 2 spaces on the right, not at the beginning of the line.
I'm new in ocaml so I don't know if this is common or not but for me sounds like if something is missing, and probably it is :)
P.S. : I know that an abs function already exists but I'm doing this to learn.
Update :
let abs_val value =
let abs_ret = ref 0 in
if value >= 0
then abs_ret := value
else abs_ret := -value in
let return : int = abs_ret;
;;
print_int abs_val -12
Am I closer right?
Sometimes it happens the syntax error is not here but above. Did you closed your previous function with ;; ? Also, what is this return ? Use the functional paradigm of the language. You use variables and references and force the type checking. I'm not sure how do you want to use this code but in a general way, try to let OCaml determine the type of your functions rather than telling the compiler what is the signature. Plus, your code shouldn't be using that much references. For instance the following :
let abs_val value =
if value < 0 then
-value
else
value
Will work perfectly and not mess up things with reference. If you wish to use references, I suggest you learn more about the functional paradigm of OCaml before going deeper into its imperative possibilities.
Your syntax error is a result of having let with no matching in.
This is a very common error when learning OCaml syntax. There are two separate uses of let in OCaml. At the top level of a module, you use let to define a symbol (a function or a value) that is one of the elements of the module. So in the following:
module M = struct
let f x = x * 2
end
The let defines a function named M.f.
Similarly your code uses let this way to define abs_val.
In other cases (not at the top level of a module), let is used only as part of the let ... in expression that looks like this:
let v = exp1 in exp2
This essentially defines a local variable v with the value exp1 that can be used in the body of exp2.
All your other uses of let (except the initial definition of abs_val) are of this second kind. However, none of them have in, so they are all syntactically incorrect.
You need to fix up these problems before you can make progress with this function. You can fix the first one, for example, by changing the first semicolon (;) to in.
As #SDAChess points out, you have a second problem with the return value of your function. There is no special return keyword in OCaml that's used to return the value of a function. A function in OCaml is just a set of nested function calls, and the value of the function is the value returned by the outermost call.
For the next code I'm getting an error:
fun epoly(L:real list, x:real)=
= if L = [] then 0.0 else (epoly(tl(L:real list), x:real));;
Error:
stdIn:42.1-42.57 Error: operator and operand don't agree [equality type required]
operator domain: ''Z * ''Z
operand: real list * 'Y list
in expression:
L = nil
Since you're not actually asking a question, it is a little unclear what your intent is. Presumably this is attempted code that doesn't work and the accompanying error message, and the implicit question is "Why doesn't this code work? What am I doing wrong, and what can I do to improve it?" But really that's guesswork, and those are lazy questions, too.
Here's how your post could look like if my assumptions above are correct and you want positive feedback in the future:
I am trying to write a function that evaluates a polynomial with real coefficients L for the variable x.
It looks like:
fun epoly (L : real list, x : real) =
if L = [] then 0.0 else epoly(tl L, x)
Unfortunately I am getting a type error that I don't understand:
stdIn:1.35-1.91 Error: operator and operand don't agree [equality type required]
operator domain: ''Z * ''Z
operand: real list * 'Y list
in expression:
L = nil
What does this error mean, and if this is not the right way to evaluate a polynomial, then what would another way to accomplish the same thing look like?
The take-aways:
Write what your problem is, don't let others assume what your problem is. Making a question easily understood makes people want to answer your question, and describing your problem in words tells what you think is the problem, so that people don't try and answer the wrong question. In this case, your question could have been "Under what version of the Standard ML specification were reals removed as an eqtype?" and a sufficient answer would have been '97. But would you have been happy about that answer?
Once you know how to ask the right question, you can also better google around (e.g. search for: evaluate polynomial "standard ml"|sml) and find that there exists code from which you can let yourself inspire: here, here, here.
Format your code nicely and make sure it works. Use StackOverflow's Markdown to format your code nicely. The code that you posted contains artifacts from the interactive REPL (an extra =), so anyone who copy-pastes it into a REPL will get an error, will have to figure out where it occurred, fix it, and then start to think about what could be the problem, since you didn't say. A good rule is to test that the code you posted works by copy-pasting it once you've asked the question. One can easily forget to include a non-standard function.
An answer, assuming my rendition of your "question" somewhat lines up with your intent:
When you do if L = [] ... then you're using equality for lists of reals, which in turn relies on equality for reals, but reals can't be compared for equality. See the Q&A "Why can't I compare reals in Standard ML?" You can test if a list of reals is empty without comparing reals by doing e.g.:
fun epoly (L, x) =
if null L then 0.0 else epoly (tl L, x)
This is because the standard library function null uses pattern matching on lists but does not address the list's elements, whereas = assumes that elements may have to be compared. Even though that never happens in practice in the example L = [], this is still an error in the type system.
If you were comparing reals for equality, consider using an epsilon test. Besides that, consider using pattern matching instead of hd and tl because those functions can fail and crash because they're partial:
fun epoly ([], x) = 0.0
| epoly (c::cs, x) = epoly (cs, x)
All this function does is throw away its second argument x, traverse its first argument, c::cs, and do nothing with each coefficient c. Presumably, in order to evaluate a polynomial, you must do something to coefficient c and x before doing the same thing recursively on the remaining coefficients cs and x, and then somehow compose those.
I am currently studying OCAML, and have a question about a user-defined if-then such as:
let cond (c,t,e) =
match c with
| true -> t
| false -> e
When used in a factorial function:
let rec fact n =
cond (n=0,1, n * fact (n-1))
Intuitively, it seems to be correct, but I know it will throw a stack overflow error. Can someone explain to me why this is, and how this user-defined if-then differs from the builtin if-then?
Basically your user defined conditional is not lazy evaluated. Before the actual match takes place, OCaml tries to evaluate both expressions you pass - for the true and false cases.
Example:
Let's suppose we try to evaluate fact 2.
The return value is the expression cond (2=0,1, 2 * fact (2-1)). Before the 3-tuple is passes to cond, it has to be fully evaluated. To do that Ocaml has to evaluate the function fact (2-1).
Now we evaluate fact 1. The return value is cond (1=0,1, 2 * fact (1-1)). Again, we need to know the value of fact (1-1), so we compute it recursively.
We evaluate fact 0. Here the problem starts to show. The return value is cond (0=0,1, 0 * fact (0-1)), but in order to evaluate the function cond we first have to evaluate its arguments - the 3-tuple. This makes us evaluate fact (0-1)!
Then, we are evaluating fact -1...
... fact -2 ... fact -3 ... and the stack overflows :)
The built-in if-then evaluates its arguments lazily: first, it checks whether the condition is true or false, then it accordingly chooses only one branch to evaluate - this behavior is called lazy evaluation.
Actually OCaml has operations lazy and force you could use to avoid this undesirable behavior, but probably it is better just to stick to traditional if.
I'm programming a simple calculator in Bison & Flex , using C/C++ (The logic is done in Bison , and the C/C++ part is responsible for the data structures , e.g. STL and more) .
I have the following problem :
In my calculator the dollar sign $ means i++ and ++i (both prefix and postfix) , e.g. :
int y = 3;
-> $y = 4
-> y$ = 4
When the user hits : int_expression1 && int_expression2 , if int_expression1 is evaluated to 0 (i.e. false) , then I don't wan't bison to evaluate int_expression2 !
For example :
int a = 0 ;
int x = 2 ;
and the user hits : int z = a&&x$ ...
So , the variable a is evaluated to 0 , hence , I don't want to evaluate x , however it still grows by 1 ... here is the code of the bison/c++ :
%union
{
int int_value;
double double_value;
char* string_value;
}
%type <int_value> int_expr
%type <double_value> double_expr
%type <double_value> cmp_expr
int_expr:
| int_expr '&&' int_expr { /* And operation between two integers */
if ($1 == 0)
$$ = 0;
else // calc
$$ = $1 && $3;
}
How can I tell bison to not evaluate the second expression , if the first one was already evaluated to false (i.e. 0) ?
Converting extensive commentary into an answer:
How can I tell Bison to not evaluate the second expression if the first one was already evaluated to false?
It's your code that does the evaluation, not Bison; put the 'blame' where it belongs.
You need to detect that you're dealing with an && rule before the RHS is evaluated. The chances are that you need to insert some code after the && and before the second int_expr that suspends evaluation if the first int_expr evaluates to 0. You'll also need to modify all the other evaluation code to check for and obey a 'do not evaluate' flag.
Alternatively, you have the Bison do the parsing and create a program that you execute when the parse is complete, rather than evaluating as you parse. That is a much bigger set of changes.
Are you sure regarding putting some code before the second int_expr ? I can't seem to find a plausible way to do that. It's a nice trick, but I can't find a way to actually tell Bison not to evaluate the second int_expr, without ruining the entire evaluation.
You have to write your code so that it does not evaluate when it is not supposed to evaluate. The Bison syntax is:
| int_expr '&&' {...code 1...} int_expr {...code 2...}
'Code 1' will check on $1 and arrange to stop evaluating (set a global variable or something similar). 'Code 2' will conditionally evaluate $4 (4 because 'code 1' is now $3). All evaluation code must obey the dictates of 'code 1' — it must not evaluate if 'code 1' says 'do not evaluate'. Or you can do what I suggested and aselle suggested; parse and evaluate separately.
I second aselle's suggestion about The UNIX Programming Environment. There's a whole chapter in there about developing a calculator (they call it hoc for higher-order calculator) which is worth reading. Be aware, though, that the book was published in 1984, and pre-dates the C standard by a good margin. There are no prototypes in the C code, and (by modern standards) it takes a few liberties. I do have hoc6 (the last version of hoc they describe; also versions 1-3) in modern C — contact me if you want it (see my profile).
That's the problem: I can't stop evaluating in the middle of the rule, since I cannot use return (I can, but of no use; it causes the program to exit). | intExpr '&&' { if ($1 == 0) {/* turn off a flag */ } } intExpr { /* code */} After I exit $3 the $4 is being evaluated automatically.
You can stop evaluating in the middle of a rule, but you have to code your expression evaluation code block to take the possibility into account. And when I said 'stop evaluating', I meant 'stop doing the calculations', not 'stop the parser in its tracks'. The parsing must continue; your code that calculates values must only evaluate when evaluation is required, not when no evaluation is required. This might be an (ugh!) global flag, or you may have some other mechanism.
It's probably best to convert your parser into a code generator and execute the code after you've parsed it. This sort of complication is why that is a good strategy.
#JonathanLeffler: You're indeed the king ! This should be an answer !!!
Now it is an answer.
You almost assuredly want to generate some other representation before evaluating in your calculator. A parse tree or ast are classic methods, but a simple stack machine is also popular. There are many great examples of how to do this, but my favorite is
http://www.amazon.com/Unix-Programming-Environment-Prentice-Hall-Software/dp/013937681X
That shows how to take a simple direct evaluation tool like you have made in yacc (old bison) and take it all the way to a programming language that is almost as powerful as BASIC. All in very few pages. It's a very old book but well worth the read.
You can also look at SeExpr http://www.disneyanimation.com/technology/seexpr.html
which is a simple expression language calculator for scalars and 3 vectors. If you look at https://github.com/wdas/SeExpr/blob/master/src/SeExpr/SeExprNode.cpp
on line 313 you will see the && implementation of he eval() function:
void
SeExprAndNode::eval(SeVec3d& result) const
{
// operands and result must be scalar
SeVec3d a, b;
child(0)->eval(a);
if (!a[0]) {
result[0] = 0;
} else {
child(1)->eval(b);
result[0] = (b[0] != 0.0);
}
}
That file contains all objects that represent operations in the parse tree. These objects are generated as the code is parsed (these are the actions in yacc). Hope this helps.