In all the examples I've seen for predicate builder it shows a starting expression with PredicateBuilder.True if you are building an "and" expression criteria and PredicateBuilder.False if you are building an "or" expression criteria.
My questions is, is this always the case, and if so why couldn't this be simply inferred. I suspect there must be cases where you are be building an "and" expression and want to start with a false. And the opposite for an "or"
Can anyone explain this to me?
In the expression A and B and C and D, if any of the conditions (A, B, C, or D) are False, the entire expression is False. So if you start an "and" expression with False, no matter what else you AND to it, the entire expression will be False.
Same with an "or" expression. In the expression A or B or C or D, if any of the conditions (A, B, C, or D) are True, the entire expression is True. So if you start an "or" expression with True, no matter what else you OR to it, the entire expression will be True.
As for why you need to start a PredicateBuilder with the literal True or False, I believe this was simply a convention to make using PredicateBuilder easier. Your expressions always start with a (boolean) condition, followed by 0 or more "And/Or condition" parts. So you can have "A", or "A and B", or "A and B and C". You never start with "and A". The .And(condition) of PredicateBuilder adds "and condition" to the expression, so you can't start with it. There could have been a constructor that let your create your Expression and start it with an initial condition (new Expression<...>(A)? I haven't actually checked... is there one?) but then you'd have to treat your first condition (you're probably looping over some collection of things and adding to your Expression) differently (calling a constructor) than you do your 2nd and subsequent conditions (calling .And(...) or .Or(...)). The .True<...>() and .False<...>() methods of PredicateBuilder handle creating your Expression as well as adding the first (generic) condition so that you can handle adding your 1st and all subsequent conditions in your loop the same (by calling .And(...) or .Or(...)).
Related
I see a code as below in https://github.com/terraform-aws-modules/terraform-aws-efs/blob/master/examples/complete/main.tf#L58
# Mount targets / security group
mount_targets = { for k, v in toset(range(length(local.azs))) :
element(local.azs, k) => { subnet_id = element(module.vpc.private_subnets, k) }
}
I am trying to understand what => means here. Also this command with for loop, element and =>.
Could anyone explain here please?
In this case the => symbol isn't an independent language feature but is instead just one part of the for expression syntax when the result will be a mapping.
A for expression which produces a sequence (a tuple, to be specific) has the following general shape:
[
for KEY_SYMBOL, VALUE_SYMBOL in SOURCE_COLLECTION : RESULT
if CONDITION
]
(The KEY_SYMBOL, portion and the if CONDITION portion are both optional.)
The result is a sequence of values that resulted from evaluating RESULT (an expression) for each element of SOURCE_COLLECTION for which CONDITION (another expression) evaluated to true.
When the result is a sequence we only need to specify one result expression, but when the result is a mapping (specifically an object) we need to specify both the keys and the values, and so the mapping form has that additional portion including the => symbol you're asking about:
{
for KEY_SYMBOL, VALUE_SYMBOL in SOURCE_COLLECTION : KEY_RESULT => VALUE_RESULT
if CONDITION
}
The principle is the same here except that for each source element Terraform will evaluate both KEY_RESULT and VALUE_RESULT in order to produce a key/value pair to insert into the resulting mapping.
The => marker here is just some punctuation so that Terraform can unambiguously recognize where the KEY_RESULT ends and where the VALUE_RESULT begins. It has no special meaning aside from being a delimiter inside a mapping-result for expression. You could think of it as serving a similar purpose as the comma between KEY_SYMBOL and VALUE_SYMBOL; it has no meaning of its own, and is only there to mark the boundary between two clauses of the overall expression.
When I read a for expression out loud, I typically pronounce => as "maps to". So with my example above, I might pronounce it as "for each key and value in source collection, key result maps to value result if the condition is true".
Lambda expressions use the operator symbol =, which reads as "goes to." Input parameters are specified on the operator's left side, and statement/expressions are specified on the right. Generally, lambda expressions are not directly used in query syntax but are often used in method calls. Query expressions may contain method calls.
Lambda expression syntax features are as follows:
It is a function without a name.
There are no modifiers, such as overloads and overrides.
The body of the function should contain an expression, rather than a statement.
May contain a call to a function procedure but cannot contain a call to a subprocedure.
The return statement does not exist.
The value returned by the function is only the value of the expression contained in the function body.
The End function statement does not exist.
The parameters must have specified data types or be inferred.
Does not allow generic parameters.
Does not allow optional and ParamArray parameters.
Lambda expressions provide shorthand for the compiler, allowing it to emit methods assigned to delegates.
The compiler performs automatic type inference on the lambda arguments, which is a key advantage.
This question already has answers here:
Pattern matching identical values
(4 answers)
Closed 10 months ago.
I want the function isValid to return True if the first and second arguments match desPlanet and currPlanet from the 3rd argument. Is there a way I can do this?
Please see -
Not like that.
Patterns can only consist of 3 things:
A constructor, applied to as many sub-patterns as the constructor has arguments. Examples are Nothing, Just (Just x), or [desPlanet, _, currPlanet]:_, etc. The pattern will match values that were constructed with the same constructor, if all of the sub-patterns match the corresponding arguments in the value.
A variable, which will simply match anything and make the matched value available under that variable name. (The variable _ is a special, since it doesn't actually make the matched value available, and can thus be used multiple times across the pattern)
A literal like 123, "foo", 'c', etc; which will be matched by equality checking. (If the literal is polymorphic, like numeric literals with the Num class, then you may need an Eq constraint)
Note that there is no option to match anything against an existing variable (or against one bound elsewhere in the same pattern). The template you're trying to check against must be statically known, it can't be referred to by a variable. You either match against a specific concrete literal, or you match against a specific concrete constructor, or you just accept anything and bind it to a variable name.
However guards do allow you to check arbitrary conditions, and if the guard condition fails then the function will fall through to its next equation (just as if a pattern failed to match). So you can still do exactly what you want ("I want the function isValid to return True if the first and second arguments match desPlanet and currPlanet from the 3rd argument"); you just don't do solely with pattern matching.
For example:
isValid currPlanet desPlanet ([desPlanet', _, curPlanet'] : _) solarSys
| curPlanet == curPlanet' && desPlanet = desPlanet'
= True
isValid ... -- other equations
What is the order in which Haskell guards are evaluated?
Say that I have a function which returns a Bool:
someFunc :: Bool -> Bool -> Bool
someFunc b1 b2
| b1 == True && b2 == True = True
| b1 == True = False
| b1 == False .....
...
I think it was with Monads and the Do-notation that I read, that actions are sometimes not evaluated sequentially. That is if I have:
do { val1 <- action1
val2 <- action2
action3 }
It might be the case that val2 will be calculated before val1.
Is this the case for guards as well? Can they be evaluated out of order?
If guards were sequential, then if the first statement evaluates to False, and the second evaluates to True, then I can conclude that b2 is False. Does this logic always hold?
Edit: By statements I mean guard 1 to 3
Evaluating the tests within guards can’t have any side-effects — unlike in procedural languages. So the order of evaluating the comparisons or Boolean connectives doesn’t make any difference to the semantics of the program.
Prioritising the branches — that is, each of the lines starting | — is from top to bottom. But really ‘evaluating’ is the wrong concept: it would be OK for the compiler to first evaluate your b1 == False, providing it didn’t take the third branch until it had checked the first two. (GHC doesn’t actually do that; I’m just setting up a straw man.)
Note that in a call to someFunc, the arguments for b1, b2 might be arbitrarily complex expressions. Haskell’s ‘Lazy semantics’ mean that neither of them are evaluated until needed.
Does this logic always hold?
Be careful: if an early guard turns out False, you can’t assume anything about the expressions in it. The compiler might have rearranged them for efficiency, evaluated one out of textual order, then moved on. In your example, if for the first branch it turned out b1 /= True, the compiler might not evaluate b2 at all. So you can’t conclude anything about b2. Indeed b2 might give bottom/infinite calculation, if evaluated.
It’s not just with Monads or Do-notation (which are the same thing) that expressions are not necessarily evaluated in textual order — that’s true across any expressions in any context. (The IO Monad has some dodgy semantics, to make it seem ‘statements’ are executed top-to-bottom.)
How would I modify the definition of the operators "&&" and "||" so that they do not use short circuit evaluation? Please show the new semantic rule.
I tried the following:
"AND (&&): It returns expression #1 if it can be converted to false - if else it returns expression #2. Therefore, when used with the Boolean value, it returns true if both operands can be converted to true; otherwise, it returns false.
OR (||): it returns expression #1 if it can be converted to true – if-else, it returns expression #2. Therefore, when used with Boolean values, || returns true if either operand can be converted to true - if both can be converted to false, it returns false. "
However, apparently, that's still using short-circuit evaluation.
Short-circuit evaluation means that you stop immediately whenever you encounter a value of false for AND and a value of true for OR. This is because the value of the entire expression will always be that no matter what the second term is.
Your AND description is wrong because if expression #1 evaluates to false, expression #2 is not evaluated at all. Same thing with OR.
What you want to do is to evaluate both expressions before manipulating either values.
I'm learning groovy to work on smartthings and found a relatively common command among the various examples and existing code (see below).
Reading the function of the && operator I would think the "&& cmd.previousMeterValue" is superfluous. Or is there some code shortcut I'm missing?
Thanks
John
if (cmd.previousMeterValue && cmd.previousMeterValue != cmd.meterValue) {
do something
}
Not knowing what type previousMeterValue has, this answer is somewhat generic.
Groovy follows common operator precedence, i.e. != is evaluated before &&.
To show it explicitly, the full expression is the same as:
(cmd.previousMeterValue) && (cmd.previousMeterValue != cmd.meterValue)
cmd.previousMeterValue is testing the value for the Groovy-Truth.
Depending on value type, the following might be applicable:
Non-null object references are coerced to true.
Non-zero numbers are true.
So if the value is null or 0, the expression is false.
If the first part of the expression evaluated to false, then the second part is skipped.
The logical && operator: if the left operand is false, it knows that the result will be false in any case, so it won’t evaluate the right operand. The right operand will be evaluated only if the left operand is true.
If the first part of the expression evaluated to true, then cmd.previousMeterValue != cmd.meterValue is evaluated, using the following rule:
In Groovy == translates to a.compareTo(b)==0, if they are Comparable, and a.equals(b) otherwise.
So if value is a number object, then it is evaluated as:
cmd.previousMeterValue.compareTo(cmd.meterValue) != 0
This means that BigDecimal values are compared by value, ignoring specific scale.