In javascript we can do this:
var x string = expr1 || expr2
If expr1 is not undefined, it will be copied to x, if it is undefined, expr2 will be copied to x. In go, we can use:
if expr1 == "" { var string x = expr1 } else { var string x = expr2 }
Is there are shorthand for this? If not, why?
I don't know about the "why" however you can always use this :
var a []string = expr1
if a == nil {
a = expr2
}
The Go Programming Language Specification
Declarations and scope
A declaration binds a non-blank identifier to a constant, type,
variable, function, label, or package. Every identifier in a program
must be declared.
The zero value
When memory is allocated to store a value, either through a
declaration or a call of make or new, and no explicit initialization
is provided, the memory is given a default initialization. Each
element of such a value is set to the zero value for its type: false
for booleans, 0 for integers, 0.0 for floats, "" for strings, and nil
for pointers, functions, interfaces, slices, channels, and maps.
Type system
Static type-checking
Dynamic type-checking
Go is a statically typed language. All variables must be declared at compile time and they have an well-defined initial value. JavaScript is a dynamically typed language. Variables are declared at run time. Therefore, the JavaScript construct makes no sense in Go.
Related
I'm working with a chart that has the following structure at the beginning but I'm having a hard time understanding when does this evaluate to true.
{{- if and .Values.vpceIngress.enabled .Values.http.paths (ne .Values.vpceIngress.class "traefik2") }}
I believe that both enabled and paths must be true, but the ne throws me off after that.
and and ne are functions in go templates.
and
Returns the boolean AND of its arguments by returning the
first empty argument or the last argument, that is,
"and x y" behaves as "if x then y else x". All the
arguments are evaluated.
ne
Returns the boolean truth of arg1 != arg2
So the template line equates to a more psuedo codish
if (
.Values.vpceIngress.enabled
&& .Values.http.paths
&& .Values.vpceIngress.class != "traefik2"
)
The truthiness of the plain .Value.key is basically a "is this field/key not the zero value for the data type. This also works for maps as 'is this field/key defined' due to a map without that path equating to nil or non value (Note that this only works when the parent map is actually defined! Otherwise the template errors)
The single pipe "or" | exists as a method on TrueClass and FalseClass, but the short circuit || operator does not. Neither does it exist as a method on Object.
This seems to be an exception to ruby's "everything is an object" metaphor.
Main Question: Syntactically speaking, what are || and &&? Are they just baked bits of global syntax?
Secondary Question: I'm flagging this as not part of the main question, because it is potentially subjective, though I suspect it probably isn't.
Is there a language design or performance reason for this asymmetry? It seems to me both operators could have been implemented as methods on Object. Something like:
class Object
def short_circuit_or(other)
!nil? ? true :
!other.nil? ? true : false
end
end
I assume there is a reason they were not. What is it?
Both | and || are operators. || is part of the language while | is implemented as a method by some classes (Array, FalseClass, Integer, NilClass and TrueClass) .
In programming languages, | is used in general as the bitwise OR operator. It combines the bits of its integer operands and produces a new integer value. When used with non-integer operands, some languages convert them to integer, others prohibit such usage.
|| is the logical OR operator. It combines two boolean values (true or false) and produces another boolean value. When its operands are not boolean values, they are converted to boolean by some languages. Ruby (and JavaScript and other languages) evaluate its first operand as boolean and the value of the expression is the value of its first operand if its boolean value is true or the value of its second operand if the logical value of its first one is false. The type of the resulting value is its original type, it is not converted to boolean.
Each language uses its own rules to decide what non-boolean values are converted to false (usually the number 0, the empty string '' and null or undefined); all the other values are converted to true. The only "false" values in Ruby are false (boolean) and nil (non-boolean); all the other values (including 0) are "true".
Because true || anything is true and false && anything is false, many programming languages including Ruby implement short-circuit evaluation for logical expressions.
Using short-circuit evaluation, a logical expression is evaluated from left to right, one operand at a time until the value of the expression can be computed without the need to compute the other operands. In the examples above, the value of anything doesn't change the value of the entire expression. Using short-circuit evaluation, the value of anything is not computed at all because it does not influence the value of the entire expression. Being anything a method call that takes considerable time to execute, the short-circuit evaluation avoids calling it and saves execution time.
As others already mentioned in comments to the question, implementing || as a method of some class is not possible. The value of its second operand must be evaluated in order to be passed as argument to the method and this breaks the short-circuiting behaviour.
The usual representation of the logical values in programming languages uses only one bit (and I guess Ruby does the same.) Results of | and || are the same for operands stored on one bit.
Ruby uses the | symbol to implement different flavors of the OR operation as follows:
bitwise OR for integers;
non-short-circuit logical OR for booleans and nil;
union for arrays.
An expression like:
x = false | a | b | c
ensures that all a, b and c expressions are evaluated (no short-circuit) and the value of x is the logical OR of the logical values of a, b and c.
If a, b and c are method calls, to achieve the same result using the logical OR operator (||) the code needs to look like this:
aa = a
bb = b
cc = c
x = aa || bb || cc
This way each method is called no matter what values are returned by the methods called before it.
For TrueClass, FalseClass and NilClass, the | operator is useful when short-circuit evaluation is not desired.
Also, for Array (an array is just an ordered set), the | operator implements union, an operation that is the semantically equivalent of logical OR for sets.
In my program I do a series of sequential checks in this manner:
var value int
if !(ParseOrFail(inputStrVal, &value) &&
Validate(value)) {
return SomeErr
}
I know that Validate is called only if ParseOrFail returns true, but I'm not sure whether in all such scenarios it will get the updated value.
Is it correct to do so? Or must I pass a pointer to Validate ?
Playground link: https://play.golang.org/p/l6XHbgQjFs
The Go Programming Language
Specification
Expressions
An expression specifies the computation of a value by applying
operators and functions to operands.
Operands
Operands denote the elementary values in an expression. An operand may
be a literal, a (possibly qualified) non-blank identifier denoting a
constant, variable, or function, a method expression yielding a
function, or a parenthesized expression.
Order of evaluation
At package level, initialization dependencies determine the evaluation
order of individual initialization expressions in variable
declarations. Otherwise, when evaluating the operands of an
expression, assignment, or return statement, all function calls,
method calls, and communication operations are evaluated in lexical
left-to-right order.
Calls
Given an expression f of function type F,
f(a1, a2, … an)
calls f with arguments a1, a2, … an. Except for one special case,
arguments must be single-valued expressions assignable to the
parameter types of F and are evaluated before the function is called.
The type of the expression is the result type of F. A method
invocation is similar but the method itself is specified as a selector
upon a value of the receiver type for the method.
Logical operators
Logical operators apply to boolean values and yield a result of the
same type as the operands. The right operand is evaluated
conditionally.
&& conditional AND p && q is "if p then q else false"
|| conditional OR p || q is "if p then true else q"
! NOT !p is "not p"
The behavior of your code is defined in The Go Programming Language Specification.
var value int
if !(ParseOrFail(inputStrVal, &value) && Validate(value)) {
return SomeErr
}
Or, in pseudocode,
ParseOrFail arguments are evaluated
ParseOrFail is called
if ParseOrFail == true
Validate arguments are evaluated
Validate is called
That is, in your example (https://play.golang.org/p/l6XHbgQjFs), late evaluation.
I recently dealt with code using a strongly typed enum that contained negative values.
When comparing the values of the enum, I got weird results when compiling the code with Clang (3.3) while Gcc works just fine.
Here is a small example with an assert that fails.
enum class T: int { A = -1, B = 1 };
int main() {
T a = T::A, b = T::B;
assert(a < b);
}
Is this an actual bug? Or does clang behave correctly and gcc just offers some kind of legacy support?
It should be more intuitive that the following is well-formed:
T a = T::A;
assert(a == T::A);
But the equality operators (==, !=) have the same restrictions as the relational operators (<, <=, ..) [expr.eq]/1:
The == (equal to) and the != (not equal to) operators have the same semantic restrictions, conversions, and result type as the relational operators except for their lower precedence and truth-value result.
So if equality between values of a scoped enumeration type is well-defined, so should < be.
[expr.rel]/1
The operands shall have arithmetic, enumeration, or pointer type, or type std::nullptr_t.
Of course, the usual arithmetic conversions are performed on operands of arithmetic or enumeration type [expr.rel]/2, where the conversion is the identity conversion for scoped enumerations (no integral promotion, see [expr]/10 first bullet). However, [expr.rel]/5 explicitly states:
If both operands (after conversions) are of arithmetic or enumeration type, each of the operators shall yield
true if the specified relationship is true and false if it is false.
(emphasis mine)
Therefore, T::A < T::B should be well-formed and yield true.
As I already wrote in a comment, the assertion doesn't fail on clang++3.4 trunk 193040. I therefore assume it's a bug that has been fixed, even though I couldn't find a corresponding bug report.
I've never used the following kind of expressions in if statements or other control structures (example in PHP):
if ( ( $p = someFunction() ) !== false ) {
// Use $p
}
I usually take this kind of assignment expression out and have it evaluated before I check it in an if statement.
My questions are:
Is there a name for this technique?
After the assignment ($p = someFunction()) what types can be tested for? (For example only true/false or the actual type someFuntion returns)?
Is this reccomended and safe to use with most languages and to expect similar behaviour?
You could name it using return value of assignment expression?
Why do you ask this generally? You have to check if your language supports this kind of code. Most C like languages return the value that is assigned to the variable on the left so it can be any type.