Kotlin is ignoring expression - kotlin

I'm wondering why the below code generates the strange results, and compiler doesn't show any error or warning. This looks like an extremely efficient source of bugs.
val a = 10 * 20 +
10 * 30
val b = 10 * 20
+ 10 * 30
val c = (
(10 * 20)
+ (10 * 30)
)
val d = (10 * 20)
+ (10 * 30)
println(a)
println(b)
println(c)
println(d)
And the output is:
500
200
500
200

Kotlin has optional semicolons, it allows and encourages source code to omit a statement separator (i.e. semicolon ;). As a result, it can get hard for the compiler to guess what you, as a programmer, actually intend to do:
val b = 10 * 20
+ 10 * 30
Will be compiled to an assignment of b = 500 and a second statement that results in 300 but never gets assigned to anything (same with d). How would you consider the compiler to know that the second line is actually part of the first expression? It's valid on its own.
This thread gives further details.

I looks like I was lucky to use an operator which also has unary version +.
The problem is that Kotlin allows for a kind of expressions which do nothing in fact like this:
12345
I can also have:
- 12345
which is just a negative number. I can also have positive number:
+ 12345
So in this case:
val a = 20 +
30
I have one expression, as the + requires another argument, which can be found in the next line.
However here I have two expressions
val a = 20
+ 30
The variable a will have value 20 and the second expression will do nothing.
However there is no unary version of *, so this works:
val a = 10 *
20
and a == 200, and this makes a compilation error:
val a = 10
* 20
Error:(397, 17) Kotlin: Expecting an element
Adding semicolons doesn't change anything, as the last expression is still not valid, and causes the compilation error.
And you can always use brackets:
val x = (10
+ 20)

Related

Kotlin line break in sums — result depends on operator placement

today I've encountered a strange behaviour in Kotlin that I cannot explain. Given the following code:
data class Data(
val v1: Int,
val v2: Int,
val v3: Int)
fun main() {
val d = Data(1,1,1)
val sum1 = d.v1 + d.v2 + d.v3
println("Oneliner: $sum1") // prints: Oneliner: 3
val sum2 = d.v1
+ d.v2
+ d.v3
println("OperatorFirst: $sum2") // prints: OperatorFirst: 1
val sum3 = d.v1 +
d.v2 +
d.v3
println("OperatorLast: $sum3") // prints: OperatorLast: 3
}
(Testable at: https://pl.kotl.in/gMjif_6FO)
Now it seems to depend on where you place the + operator to get the correct result of 3. However, the IDE doesn't show that anything might be wrong with the second version and i couldn't find any information of why this case would behave differently.
A question on the software engineering space also says that several coding guidelines suggest to put the operator at the beginning of the line: https://softwareengineering.stackexchange.com/questions/93670/line-break-before-after-operator
Also, the only explanation I could find for this behaviour is that the + at the line beginnings is interpreted as a unary plus operator. https://www.programiz.com/kotlin-programming/operators#unary
However, even this makes no sense to me on a val
That's the price you pay for optional semicolons. Andrey Breslav said in one of his lectures that it is intended behavior. Binary operators like + or * should be placed on the top line, not the bottom line. If you want to place them on bottom line, use parentheses:
val sum = (1
+ 1
+ 1)
println(sum) // prints: 3

Map signature mismatch with Whatever? x vs X vs xx

The last line here results in a incorrect signature to the map call:
my #array=[0,1,2];
say "String Repetition";
say #array.map({($_ x 2)});
say #array.map: * x 2;
say "\nCross product ";
say #array.map({($_ X 2)});
say #array.map: * X 2;
say "\nList Repetition";
say #array.map({$_ xx 2});
say #array.map: * xx 2;
The output being:
String Repetition
(00 11 22)
(00 11 22)
Cross product
(((0 2)) ((1 2)) ((2 2)))
(((0 2)) ((1 2)) ((2 2)))
List Repetition
((0 0) (1 1) (2 2))
Cannot resolve caller map(Array:D: Seq:D); none of these signatures match:
($: Hash \h, *%_)
(\SELF: █; :$label, :$item, *%_)
The x operator returns a Str, the X returns a List of Lists and the xx return a List.
Is this changed somehow using the Whatever. Why is this error happening? Thanks in advance
Let me see if I can get this through clearly. If I don't, please ask.
Short answer: xx has a special meaning together with Whatever, so it's not creating a WhateverCode as in the rest of the examples.
Let's see if I can get this straight with the long answer.
First, definitions. * is called Whatever. It's generally used in situations in which it's curried
I'm not too happy with this name, which points at functional-language-currying, but does not seem to be used in that sense, but in the sense of stewing or baking. Anyway.
Currying it turns it into WhateverCode. So an * by itself is Whatever, * with some stuff is WhateverCode, creating a block out of thin air.
However, that does not happen automatically, because some times we need Whatever just be Whatever. You have a few exceptions listed on Whatever documentation. One of them is using xx, because xx together with Whatever should create infinite lists.
But that's not what I'm doing, you can say. * is in front of the number to multiply. Well, yes. But this code in Actions.nqp (which generates code from the source) refers to infix xx. So it does not really matter.
So, back to the short answer: you can't always use * together with other elements to create code. Some operators, such as that one, .. or ... will have special meaning in the proximity of *, so you'll need to use something else, like placeholder arguments.
The xx operator is “thunky”.
say( rand xx 2 );
# (0.7080396712923503 0.3938678220039854)
Notice that rand got executed twice. x and X don't do that.
say( rand x 2 );
0.133525574759261740.13352557475926174
say( rand X 1,2 );
((0.2969453468495996 1) (0.2969453468495996 2))
That is xx sees each side as something sort of like a lambda on their own.
(A “thunk”)
say (* + 1 xx 2);
# ({ ... } { ... })
say (* + 1 xx 2)».(5);
# (6 6)
So you get a sequence of * repeated twice.
say (* xx 2).map: {.^name}
# (Whatever Whatever)
(The term *, is an instance of Whatever)
This also means that you can't create a WhateverCode closure with && / and, || / or, ^^ / xor, or //.
say (* && 1);
# 1
Note that * also does something different on the right side of xx.
It creates an infinite sequence.
say ( 2 xx * ).head(20);
# (2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2)
If xx wasn't “thunky”, then this would also have created a WhateverCode lambda.

WhateverStar `&&` WhateverStar in Perl 6

* > 20 && * %% 5 used in grep seems wrong, does is equal to a WhateverCode lambda that takes 2 arguments? As this explain on SO
> my #a = 1,12,15,20,25,30,35,37;
> #a.grep: * > 20 && * %% 5 # The result seems strange, expected (25 30 35)
(15 20 25 30 35)
> #a.grep: * %% 5 && * > 20
(25 30 35 37)
> #a.grep: { $_>20 && $_ %% 5 }
(25 30 35)
> #a.grep: all(* > 20, * %% 5)
(25 30 35)
> #a.grep: -> $a { all($a > 20, $a %% 5) }
(25 30 35)
> #a.grep: -> $a {$a > 20 && $a %% 5}
(25 30 35)
Golfed
my &or = * == 1 || * == 2 ;
my &and = * == 1 && * == 2 ;
say .signature, .(1), .(2)
for &or, ∧
displays:
(;; $whatevercode_arg_1 is raw)TrueFalse
(;; $whatevercode_arg_4 is raw)FalseTrue
I still don't know what's going on [ed: that is, I didn't at the time I wrote this paragraph; I kept what I wrote in this answer as the mystery unfolded], but it's clear that the signature is for just one arg and the result is as per just the right hand expression for the &and and the left hand for the &or which means the code doesn't seem to have, er, left the result that's, er, right. Investigation continues... (and no, I'm not det remiker).
Mystery solved
So, it looks like the logical ops (&&, ||, and, or, etc.) don't do Whatever-currying. Which is fair enough given that "not all operators and syntactic constructs curry * (or Whatever-stars) to WhateverCode". Logical, even, given their nature. They probably ought to be added to the table of exceptions on that page though.
In the meantime, operators like == do Whatever curry. Again, that's fair enough given "subexpressions may impose their own Whatever star rules".
So it makes sense that &or and &and turn in to...
Aha! Got it. The * == 1 and * == 2 are evaluated at compile-time and turn into WhateverCodes. As WhateverCodes they are just bits of code. They are defined. They are True. (This ignores calling them at run-time.) Then along comes the && and evaluates to the right hand WhateverCode. (The || would evaluate to its left hand WhateverCode.)
Hence the behavior we see.
A solution
Per prompting by #HåkonHægland, the code that would work is therefore code that doesn't rely on logical ops Whatever-currying, i.e.:
my #a = 1,12,15,20,25,30,35,37;
say #a.grep: { $_ > 20 && $_ %% 5 } # (25 30 35)
Now what?
Now we have to figure out what doc edits to propose...
Actually, before we do that, confirm that logical ops are supposed to not Whatever-curry...
And to start that ball rolling, I just trawled the results of a search for TimToady comments on #perl6 about "currying" (there were none on #perl6-dev), looking for ones pertinent to the case we have here.
First, one from 2017 that's arguably relevant to any doc edits:
the design docs actually try to avoid the word "currying" ... but it's hard to get people to use words differently than they do
Next, one from 2015 about && and || and such:
|| and && and such are really control flow operators, turned rather rapidly into 'if' and 'unless' ... those ops can be curried with .assuming, I assume
And finally a couple from 2010 that also seem potentially important (though perhaps one or more are no longer applicable?):
all operators autocurry a WhateverCode, whether or not they curry a Whatever
I think we can keep the current mechanism as a fallback for operators that still want to curry at run time
> my $d = * + * + *
> $d.arity
3
> my $e = * == 1 || * == 2 || * == 3
> $e.arity
1
as the doc say:
Returns the minimum number of positional arguments that must be passed in order to call the code object.
so I think the all three star in * == 1 || * == 2 || * == 3 is the same thing.
> my $e = * == 1 && * == 2 && * > 3
> $e(1)
False
> $e(2)
False
> $e(3)
False
> $e(4)
True

weird operator precedence and assignment behavior in borland turboC++

I have to use borland TurboC++ for C programming in my college.
They say our examination board recommends it. I have to use it..
The problem is that they gave this operator precedence related question:
int a=10,b=20,result;
result1 = ++a + b-- - a++ * b++ + a * ++b;
printf("result=%d",);
printf("\n a=%d",a);
printf("\n b=%d",b);
Other compilers like gcc can't perform this operation. But turbo C can and gives us:
result=32
a=12
b=21
I made mistake in my test. My teacher tried to explain what's going on. But I am not convinced. Is it some kind of weird behavior of turbo C or in older days it used to be totally fine with all compilers. If so, what are the steps to understand what is going on and how to understand.
To solve these kind of problem, turbo-c do it in manner as follows :
1) Consider the initial value of variables used.
a=10
b=20
2) Count all the pre-increment and decrements for each variable and store all post on stack separate for each variable.
for variable a
pre increment = 1 therefore change the value of a to 11
post = 1 stored to stack
for variable b
pre increment = 1 therefore change the value of b to 21
post = 2 stored to stack
3) Now replace all the pre and post with the current value of a and b
result = 11 + 21 - 11 * 21 + 11 * 21 ;
result = 11 + 21;
result = 32;
4) lastly pop the stack and perform the operation on the variable.
a = 12
b = 21
This the only way to solve this problem. You can check the procedure with any question of same kind. The result will came out same. g++ fails to solve because it probably cannot resolve the variable in the same way thus the precedence error came in picture. It might probably fail with ++ + and -- - because it cannot understand the increment or decrements operator and forms ambiguous trees.

How to see what the is being compared in a if statement

I'm having a problem with some vba code.
I have a if statement that doesn't treat the same content equally.
e.g: 0,1 equals 0,1, but a re-run 0,1 does not equal 0,1
(this values are shown by MVBA)
The code is long so before posting it i would like to know if it's possible to see the machine perspective in a if statement (hex, ascii...). This because, although the debug is telling me they are the same (through msgbox, vartype, etc), the if statement is not activated.
pseudo code:
x = 0,0000001 * 1*10^6 (which equals 0,1)
y = 0,0001 * 1*10^3 (which also equals 0,1)
if statement:
x doesn't enter
y does
end if
This is because the floating-point implementation may not be able to represent those number accurately due to the fact that they are encoded in a base 2 representation.
If you want to compare them, I would suggest using Cdec (wich converts to Decimal, a VBA custom base 10 floating-point)
Debug.Print (0.0000001 * 1 * 10 ^ 6) = (0.0001 * 1 * 10 ^ 3) ' False
Debug.Print CDec(0.0000001 * 1 * 10 ^ 6) = CDec(0.0001 * 1 * 10 ^ 3) ' True
While they both display 0.1, in fact 0.0000001 * 1 * 10 ^ 6 flaoting-point value is 0x3FB9999999999999 whereas 0.0001 * 1 * 10 ^ 3 returns 0x3FB999999999999A.
I'd recommend reading What Every Computer Scientist Should Know About Floating-Point Arithmetic