Can someone explain why my logic is not working?
COUNTD(IF([PlacementType] = "Programmatic Jobs" AND ISNULL([TMPProgrammaticCost]) = FALSE)
THEN ATTR([spATSApplications].[Job Title])
END)
Error message: cannot mix aggregate and non-aggregate comparisons or results in 'if' expression
Related
With Lua 5.4:
function f()
return 1
::LABEL::
end
print(f())
I got error:
lua: _.lua:3: 'end' expected (to close 'function' at line 1) near '::'
while
function f()
if true then return 1 end
::LABEL::
end
print(f())
works fine.
I don't understand that error.
Labels syntactically are statements. This can be seen from the grammar in the reference manual:
stat ::= label | ...
A return statement is syntactically required to be the last statement in a block:
block ::= {stat} [retstat]
The following Lua code would throw a similar syntax error:
function f()
return
x = 1
end
simply because the assignment x = 1, a statement just like labels, comes after the return. Simply put, return ... must be followed by end. The rationale for this presumably is that Lua doesn't want to allow "dead code" (although this isn't really valid for labels); IIRC it also resolves a syntactical ambiguity.
If you wrap the return in a block, the syntax error is fixed - the return now is the last statement in the block, there are no "dead statements" after it:
function f()
if 1 then return end -- return is followed by end - all is well (syntactically)!
x = 1 -- this is still dead code (semantically)
end
Lua can't and won't semantically analyze your code to determine that the assignment to x is still dead code.
This is used for quick'n'dirty insertion of early returns during debugging: You can simply wrap them in do ... end:
function f()
do return end -- syntactically valid, equivalent to commenting out the rest of the function
x = 1
end
getting an error when I try to run this line of code and I can't figure out why
let validCol column value : bool =
for i in 0..8 do
if sudokuBoard.[i,column] = value then
false
else true
As Tyler Hartwig says a for loop cannot return a value except unit.
On the other hand, inside a list comprehension or a seq Computation Expression you can use for to yield the values and then test if the one you are looking for exists:
let validCol column value : bool =
seq { for i in 0..8 do yield sudokuBoard.[i,column] }
|> Seq.exists value
|> not
In F#, the last call made is what is returned, you have explicitly declared you are returning a bool.
The for loop is unable to return or aggregate multiple values, bun instead, returns unit.
let validCol column value : bool =
for i in 0..8 do
if sudokuBoard.[i,column] = value then
false
else
true
Here, you'll need to figure out how to aggregate all the bool to get your final result. I'm not quite sure what this is supposed to return, or I'd give an example.
It looks like you are looking for a short-cut out of the loop like in C# you can use continue, break or return to exit a loop.
In F# the way to accomplish that with performance is to use tail-recursion. You could achieve it with while loops but that requires mutable variables which tail-recursion doesn't need (although we sometimes uses it).
A tail-recursive function is one that calls itself at the very end and doesn't look at the result:
So this is tail-recursive
let rec loop acc i = if i > 0 then loop (acc + i) (i - 1) else acc
Where this isn't
let rec loop fib i = if i < 1 then 1 else fib (i - 1) + fib (i - 2)
If F# compiler determines a function is tail-recursive the compiler applies tail-recursion optimization (TCO) on the function, basically it unrolls it into an efficient for loop that looks a lot like the loop would like in C#.
So here is one way to write validCol using tail-recursion:
let validCol column value : bool =
// loops is tail-recursive
let rec loop column value i =
if i < 9 then
if sudokuBoard.[i,column] = value then
false // The value already exists in the column, not valid
else
loop column value (i + 1) // Check next row.
else
true // Reach the end, the value is valid
loop column value 0
Unfortunately; F# compiler doesn't have an attribute to force TCO (like Scala or kotlin does) and therefore if you make a slight mistake you might end up with a function that isn't TCO. I think I saw GitHub issue about adding such an attribute.
PS. seq comprehensions are nice in many cases but for a sudoku solver I assume you are looking for something that is as fast as possible. seq comprehensions (and LINQ) I think adds too much overhead for a sudoku solver whereas tail-recursion is about as quick as you can get in F#.
PS. In .NET 2D arrays are slower than 1D arrays, just FYI. Unsure if it has improved with dotnet core.
F#'s Condtional Expressions require a condition to check, a branch for true, and a branch for false. For example:
let x =
if ("hello" = null)
then true
else false //error if else branch missing
However, something gets weird when unit, aka (), is involved.
let y =
if ("hello" = null)
then raise <| new ArgumentNullException()
else () //happy with or without else branch
And more simply:
let z =
if ("hello" = null)
then ()
else () //happy with or without else branch
Why isn't anelse branch required when unit is returned?
Consider the following code:
let f a = if a > 5 then true
If you call f 10, it returns true.
Now, ask yourself this: what should f 2 return? I know you're going to say false, but how does the compiler know that? I mean, it's just as likely that you meant it to return true in both cases, isn't it? Or even, perhaps, crash in the a <= 5 case, who knows?
So in order for the program to be "complete" (i.e. contain instructions for what to do in every situation), you always have to specify an else branch.
unit, however, is special.
Returning unit means that there is no meaningful return value. Essentially unit stands for side-effect: it means that the thing that returned it was meant to produce some effect in the external world. Since F# is not a pure language, such unit-returning things are quite ubiquitous. For example, debug logging:
let f x =
if x < 42 then printfn "Something fishy, x = %d" x
x + 5
With such statements, there is no ambiguity: it's always known that the else branch is meant to return () as well. After all, there are no other values of unit, are there? At the same time, always adding else () at the end would be very tiresome and obfuscating. So, in the interest of usability, the compiler doesn't require an else branch in this specific case.
In F# if is an expression and not a statement. Every expression needs to return a value. And both if and else need to return same type of value, because F# is strongly typed language. So if there is no else branch then by default it has type unit, but if your if returns a value with a type other thanunit, then you need to have an else with the same type.
The types of the values produced in each branch must match. If there is no explicit else branch, its type is unit. Therefore, if the type of the then branch is any type other than unit, there must be an else branch with the same return type.
If you remove else from the first snippet, it's equivalent to
let x =
if ("hello" = null)
then true
else ()
which doesn't typecheck.
Why? I'd guess for compatibility with OCaml.
The else expr3 part can be omitted, in which case it defaults to else (). (7.7.2)
You can think of unit-returning if as an equivalent to the C-like if statement as opposed to the expression.
Question already answered so I am just going to follow-up with my own superficial observations
In F# we don't have statements and expressions. In F# we compose computations using expressions alone. This is a good thing.
In C# where if is a statement this makes sense
if(x)
{
return 1;
}
If x is true the execution is stopped and we return to the caller the result: 1.
In F# where if an expression it means that if is supposed to produce a value regardless what branch has been taken. Therefore this makes little sense
if x then 1 // What value should else branch evaluate to?
We have to specify both branches
if x then 1 else 0
As the other answers indicate there is a special case when else is omitted. The if expression will produce a unit value, the closest thing we get to a statement in F#.
Because the type of the if expression is unit the "true" branch must be of type unit.
if x then () // This works
if x then () else () // This works
if x then 1 // This won't work, type mismatch
I am new to Erlang. I have a project for school which uses an ets:table.
But before I want to get some data out of the ets:table, I want to use an if-structure for checking out the table if it isn't empty.
if
ets:first(Cal) =/= '$end_of_table' ->
Event = ets:first(Cal),
{TimeAtStart, Ref} = Event,
NowTime = now(),
Ms = timer:now_diff(NowTime, TimeAtStart)div 1000
end,
Now this gives me an error: Illegal guard expression.
I don't know what I'm doing wrong, please help.
With friendly regards
Daan
if expect a guard sequence. so it fails. You could make the test before the if, and use the result, but with your code, when you get '$end_of_table', it will fails also since you have not true statement.
I recommend to use a case statement for your code:
case ets:first(Cal) of
'$end_of_table' ->
{error,no_entry};
{TimeAtStart, _Ref} ->
{ok,timer:now_diff(now(), TimeAtStart)div 1000}
end,
The illegal guard statement comes from calling the ets:first(Cal) function from within an if statement guard. so if ets:first(Cal) =/= '$end_of_table' -> is not going to compile correctly. Guard statements only have a small set of functions that can be used, read about them here.
Also if statements are a little different in Erlang vs. other languages. One clause at least must evaluate to true. The Documentation on if statements explains this behavior, and how an error is thrown if no clause evaluates to true.
So moving the ets:first(Cal) outside of the if statement and adding a catch all true case to your code, should work:
Res = ets:first(Cal),
if
Res =/= '$end_of_table' ->
Event = ets:first(Cal),
{TimeAtStart, Ref} = Event,
NowTime = now(),
Ms = timer:now_diff(NowTime, TimeAtStart)div 1000;
true -> ok %% you need a default clause
end,
However, if it was me doing my school project, I would try to use the ets:info function to check the size of the table, and do it inside of a case statement. Checkout the Documentation on the ets:info function, and the case statement.
Just FYI: I don't think I have used an if statement the entire time I have been programming in Erlang.
I have this Erlang code:
not lists:any(fun(Condition) ->Condition(Message) end, Conditions).
Can anyone please explain the entire statement in layman's terms? For your information Condition is a function, Conditions is an array. What does fun(Condition) ->Condition(Message) end mean? As well as meaning of not lists:any.
fun(Condition) ->Condition(Message) end
is a lambda function that applies the function Condition to the value of Message (taken as a closure on the surrounding code).
lists:any
is a function that takes a predicate and a list of values, and calls the predicate on each value in turn, and returns the atom true if any of the predicate calls do.
Overall, the result is the atom true if none of the Condition functions in the list Conditions return true for the Message value.
EDIT -- add documentation for lists:any
any(Pred, List) -> bool()
Types:
Pred = fun(Elem) -> bool()
Elem = term()
List = [term()]
Returns true if Pred(Elem) returns true for at least one element Elem in List.
Condition is something that takes a message and returns a boolean if it meets some criteria.
The code goes through the list of conditions and if any of them say true then it returns false, and if all of them say false it says true.
Roughly translated to verbose pseudo-Python:
def not_lists_any(Message,Conditions):
for Condition in Conditions:
if Condition(Message):
return False
return True
One step behind syntax and stdlib description which you have in other answers:
This code looks very much like an Erlang implementation of chain-of-responsibility design pattern. The message (in OOP sense of the word) "traverses" all possible handlers (functions from Conditions array) until someone can handle it. By the author's convention, the one which handles the message returns true (otherwise false), so if nobody could handle the message the result of your expression as a whole is true:
% this is your code wrapped in a function
dispatch(Message, Handlers) ->
not lists:any(fun(Condition) ->Condition(Message) end, Handlers).
It may be used like this:
CantHandle = dispatch(Event, Handlers),
if CantHandle->throw(cannot_handle); true->ok end.