I'm fairly new to Visual Basic (my background is mostly C#) so I only recently found out that ++i is not the same thing as i+=1 in VB.NET. However, my VB.NET code still compiles when I pass ++i as a parameter, even though it doesn't increment the variable:
++i 'doesn't compile
i++ 'doesn't compile
Foobar(i++) 'doesn't compile
Foobar(++i) 'compiles, but doesn't increment i
The fact that the last statement above doesn't cause an error leads me to wonder if ++ actually does mean something in VB.NET, just not what I thought it meant at first. If it doesn't, is there some other reason it isn't causing an error?
It is just the unary version of the + operator (see docs) applied twice.
Foobar(++i)
Foobar(+(+i))
Foobar(+(+(i)))
' These are all the same
For numerical values, the unary + (i.e. the + operator without second operand) does nothing:
If expression2 is absent, the + operator is the unary identity operator for the unchanged value of an expression.
However, it is not entirely clear from the docs what it will do to non-numeric values. The docs explain various cases with two operands, which all don't seem to apply here.
There is even one sentence that sounds like it could be applied, but it does not do what it says if used with unary +:
If either Object expression evaluates to Nothing or DBNull, the + operator treats it as a String with a value of "".
So you would expect that +Nothing gives "" as well, but it gives 0 instead. In fact, it appears that the unary + converts non-numerical types to Double, including strings for which + would otherwise mean concatenation (for example +"1.234" gives 1.234, and +"Hello" gives an error that this string cannot be converted to Double - and with Option Strict On, you can't convert any string implicitly anyway). It seems to behave more like a binary + with 0.0 as first operand.
You can also overload the unary + separately from the binary + and give it a different meaning entirely*. (Or do the opposite - make it do nothing even on a non-numeric type, such as what TimeSpan does - it returns the original timespan again when unary + is applied on it, and not a Double.)
*: Which probably is not such a good idea though. When overloading an operator, the meaning of it should always be intuitive.
There is no ++ operator in VB. The + unary operator is just like the - unary operator applied to a number. Numbers are positive by default but, just as you can explicitly make a number negative by prefixing it with a - operator, you can make it explicitly positive by prefixing it with a + operator. You can use as many + operators as you like. Similarly, you can use as many - operators as you like. The difference is that + operators don't change the value where - operators do.
In C-based languages, assignments actually return a value where they don't in VB. In C#, you can do this:
i += 1
and it will get the value of i, add 1 to it, assign the result back to i and then return that result, so you can use that expression where a value is expected. In VB, it does all the same things up to the assignment but it does not return a value, so you cannot use that expression where a value is expected.
In C-based languages, where you place the ++ operator makes a difference. The expression:
++i
increments i and returns the final value, whereas this expression:
i++
increments i and returns the original value. That's why some argue that the C++ language should actually be named ++C.
Related
I used an || operator within the Kotlin IDEA but was throwing an error. This confused me, one of the first queries when searching google was a closed stack overflow thread with a snarky "answer" comment which wasn't helpful.
The first query in google hit is some function "or" gibberish.
My code:
if(inputAmount >= 0 || inputAmount = -99)
I understand what is "wrong". there was some logic errors the second part of the "if" statement should have been inputAmount == -99. In my case, the code needed to further be adjusted because of the actual type that was being used.
if(inputAmount >= 0.0 || inputAmount.toInt() == -99)
This appears to be different then other languages in that other languages just simply allow you to have your "logic" error with the "inputAmount = -99". So the '||' operator is allowed and is similar to most other languages.
So first step if encounter this error is to make sure your logic is correct. (check)
infix functions > sense according to the documentation "or" and "and" are infix functions that don't use the short circuit, is it technically wrong to call the "||" operator an "or" operator and should be called logical 'or'?
when referring to the infix 'or' how do people refer to that in Kotlin?
in boolean logic takes statements. A=b is a statement that is always true
No, it isn't. In C, C++ and Java it's an expression, and its value is the value of b. If b is false, it's false, if b is 10, it's 10. And you really don't want to confuse "statements" in programming languages with "statements" in logic; they are entirely different things.
Separately, C and C++ (but not Java) allow || to work on all integral types, and not just booleans (because they didn't originally have booleans as a separate type).
when referring to the infix function 'or' how do Kotlin folk typically refer to that?
Bitwise or for integral types, and I've never actually seen anyone use non-short-circuiting or on booleans, but if I had to I'd call it... well, non-short-circuiting or.
is it technically wrong to call the "||" operator an "or" operator and should be called logical 'or'
Both || and or (on booleans) are "logical 'or'" and I don't see any problem with calling them simply 'or'. If you need to distinguish use short-circuiting vs non-short-circuiting. But again, I've never actually ran into a use of the non-short-circuiting version.
I have a basic question for my general knowledge of Kotlin concerning the mathematical operators:
I was writing an equation and I mistakenly put the plus sign on the second line which caused my equation not to work as on the examples below:
val x = 2 + 3 //x = 5 CORRECT
val x = 2 +
3 //x = 5 CORRECT
val x = 2
+ 3 //x = 2 WRONG
My question is: why Kotlin is not showing any error message on the last example? How is Kotlin interpreting the line "+3"?
val x = 2 is correct expression, so compiler uses it as complete expression.
+ 3 is correct expression although it doing nothing.
val x = 2 + is uncompleted expression - the compiler is trying to complete it using the next line.
This is an unfortunate result of the way Kotlin assumes a semicolon at the end of lines.
In languages like Java, every statement must end with a semicolon, so there's no ambiguity.
Kotlin allows you to omit semicolons, which can be handy. But it's a bit over-eager: it infers one at the end of every line that would make sense on its own, ignoring the following lines. This is rather annoying to those of us who like to put operators at the start of a line, not the end…
Most of the time, the following line won't make sense on its own, so you get a compiler error to warn you of the issue. Unfortunately, you've found one of the rare cases where the following line is valid, and so there's no error! (Kotlin has a unary plus to match its unary minus, so +3 is a number just like -4. And a number on its own is a valid expression. Kotlin calculates the value, and then discards it.)
The solutions are:
Put the whole expression on the one line. (Which is unwieldy if it's long!)
Put the operator at the end of the previous line. (Which is clearly what the language designers expect, but some of us find less logical and less clear.)
Prevent the first line from making sense on its own.
The best way I've found to do that last one is with parens:
val x = (2
+ 3)
It looks awkward in a very short expression, but it works reasonably well on longer ones — not ideal, but necessary unless/until Kotlin gets smarter about where to assume semicolons…
I've come across some code that looks something like this
If (condition) Then
array(index) = array(index) Or variable
End If
Being unfamiliar with VB, it looks to me like some kind of horrid result of a love affair between an assignment statement and a condition clause.
Functionally, I thought it looked like some kind of ?: ternary operation. I now assume it is, though certainly not in a form I'm used to.
I'm aware that the first branch will assign array(index) to itself, that's essentially how the code I'm working on works. I don't THINK it's relevant to the question, but it kinda weirds me out, and there is often more going on than what I realize with VB.
Not a duplicate of Is there a conditional ternary operator in VB.NET? since that question is asking if there IS one, rather than "what the heck does this mean"
What it's not.
There is no ternary operator in VBA. The closest you get is IIf, which evaluates both true and false expressions (so don't use it when either branch has side-effects!):
IIf({bool-expression}, {value-if-true}, {value-if-false})
So it's not anything like a ternary.
We don't know what's in array(index), but let's assume it's some Long:
array(index) = SomeLongInteger Or variable
What you're looking at is a regular assignment:
foo = 42 Or variable
The runtime is going to assign foo with a value. So first it must compute the right-hand side of the assignment (=) operator:
42 Or Variable
The Or operator is often used as a logical operator in Boolean expressions.
However the above expression isn't a Boolean expression, and the Or operator isn't a logical operator here.
What it is.
It's a bitwise operator (in VB the logical and bitwise operators are the same, which is indeed a bit (pun not intended) confusing). In the assignment foo = 42 Or Variable, foo will take the value of the bitwise comparison of 42 Or Variable.
Debug.Print 42 Or 12 'prints 46
How?
Think in binary. This is 42:
00101010
This is 12:
00001100
Then you bitwise-or the two values (remember your truth tables? True Or True = True; True Or False = True; False Or False = False) and you get this:
00101110
..which is the binary representation for - that's right - 46.
So, array(index) = array(index) Or variable does the following:
Read the value of array(index)
Read the value of variable
Bitwise-Or the two values
Assign the result of that operation back to array(index)
So, I'm writing a language using flex/bison and I'm having difficulty with implementing identifiers, specifically when it comes to knowing when you're looking at an assignment or a reference,
for example:
1) A = 1+2
2) B + C (where B and C have already been assigned values)
Example one I can work out by returning an ID token from flex to bison, and just following a grammar that recognizes that 1+2 is an integer expression, putting A into the symbol table, and setting its value.
examples two and three are more difficult for me because: after going through my lexer, what's being returned in ex.2 to bison is "ID PLUS ID" -> I have a grammar that recognizes arithmetic expressions for numerical values, like INT PLUS INT (which would produce an INT), or DOUBLE MINUS INT (which would produce a DOUBLE). if I have "ID PLUS ID", how do I know what type the return value is?
Here's the best idea that I've come up with so far: When tokenizing, every time an ID comes up, I search for its value and type in the symbol table and switch out the ID token with its respective information; for example: while tokenizing, I come across B, which has a regex that matches it as being an ID. I look in my symbol table and see that it has a value of 51.2 and is a DOUBLE. So instead of returning ID, with a value of B to bison, I'm returning DOUBLE with a value of 51.2
I have two different solutions that contradict each other. Here's why: if I want to assign a value to an ID, I would say to my compiler A = 5. In this situation, if I'm using my previously described solution, What I'm going to get after everything is tokenized might be, INT ASGN INT, or STRING ASGN INT, etc... So, in this case, I would use the former solution, as opposed to the latter.
My question would be: what kind of logical device do I use to help my compiler know which solution to use?
NOTE: I didn't think it necessary to post source code to describe my conundrum, but I will if anyone could use it effectively as a reference to help me understand their input on this topic.
Thank you.
The usual way is to have a yacc/bison rule like:
expr: ID { $$ = lookupId($1); }
where the the lookupId function looks up a symbol in the symbol table and returns its type and value (or type and storage location if you're writing a compiler rather than a strict interpreter). Then, your other expr rules don't need to care whether their operands come from constants or symbols or other expressions:
expr: expr '+' expr { $$ = DoAddition($1, $3); }
The function DoAddition takes the types and values (or locations) for its two operands and either adds them, producing a result, or produces code to do the addition at run time.
If possible redesign your language so that the situation is unambiguous. This is why even Javascript has var.
Otherwise you're going to need to disambiguate via semantic rules, for example that the first use of an identifier is its declaration. I don't see what the problem is with your case (2): just generate the appropriate code. If B and C haven't been used yet, a value-reading use like this should be illegal, but that involves you in control flow analysis if taken to the Nth degree of accuracy, so you might prefer to assume initial values of zero.
In any case you can see that it's fundamentally a language design problem rather than a coding problem.
I'd like a little clarification on the precedence of the return
statement, which appears to go against the general precedence
rules.
For example the expression
^ 2 + 3.
returns 5(which is what I want) but shouldn't it return just 2 since Unary operators
of which ^ is one has higher precedence over + which is Binary?.
There are no "unary operators" in Smalltalk. There are only 3 precedence levels: unary messages ("receiver message"), binary operators ("receiver + argument"), and n-ary keyword messages ("receiver message: argument1"). In all cases the receiver comes first.
So "^" is not an operator, but indicates a return statement. Similarly, in "-4" the "-" is not an operator but part of the number literal.
The return symbol, ^, is one of the few language built-ins constructs. Smalltalk will return the value of the expression following the ^ symbol.
Is Smalltalk's ^ really an operator at all ? I guess it is rather a reserved symbol. And what should happen to the "dangling" + 3 then, when the surrounding method has returned? I think the behavior is correct as the return statement is the last statement to happen in a "normal" Smalltalk method.
Regards