Kotlin-js: Define number of decimals - kotlin

Let's imagine something like this:
var num: Float = 0.0f
num = 2.4 * 3.5 / 3.8
num has several decimals, but I want only 2.
In JS I would use num.toFixed(2).
Other answers here suggest to use "%.2f".format(num) or num.format(2). The latter needs a custom extension fun:
fun Double.format(digits: Int) = java.lang.String.format("%.${digits}f", this)
However, any of these options leads to a compiler error of "unresolved reference". I don't think is a question of imports cause the compiler would suggest it.
Is there an easy way to do this?

Kotlin standard library for JS doesn't have anything like Double.format yet, but you can implement it easily with aforementioned toFixed function available in javascript:
fun Double.format(digits: Int): String = this.asDynamic().toFixed(digits)
fun Float.format(digits: Int): String = this.asDynamic().toFixed(digits)
This works because Double and Float in Kotlin are represented with Number data type in JS, so you can call toFixed() function on instances of those types.

Related

Same type for receiver and argument in Kotlin function

Is there any difference between these two Kotlin extension functions?
fun Any?.f(o: Any?) = 100
fun <T> T.g(o: T) = 100
Is it possible to rewrite g in such a way that the type of its argument and receiver are forced to be the same?
That is, 10.g(5) and "x".g("y") are OK, but 10.g("y") does not compile.
Edit:
Given this, I guess the answer to my second question is no, uless one adds additional arguments.
I believe this is not possible officially at the time of writing this answer (Kotlin 1.7.20).
However, internally Kotlin compiler supports such case, it allows to change the default behavior and use exact type parameters. This is controlled by the internal #Exact annotation and it is used in many places across the Kotlin stdlib.
With some hacking we can enable this behavior in our own code:
#Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
fun <T> #kotlin.internal.Exact T.g(o: #kotlin.internal.Exact T) = 100
Of course, this is purely a hack and it may stop working in future versions of Kotlin.
Update
Answering your first question on whether there is a difference between using Any and T. Generic functions make the most sense if the type parameter is not only consumed, but also passed somewhere further. For example, if the function returns T or it receives an object that consumes T:
fun main() {
var result = 5.g(7)
}
fun <T> T.g(o: T): T = if (...) this else o
In this case result is of type Int. If we use Any instead of T, result would have to be Any as well.

Analogue of infix function from Kotlin in Java

Trying to understand deeply in infix functions. Could you please give an example of solution from Java which could be solved by infix from Kotlin.
PS Please let me know if my question is incorrect if you want to devote it. It helps me asking better questions
Kotlin supports operator overloading and infix functions, Java doesn't support either.
These language features are just syntactic sugar. Everything you do with operators or infix functions can be done without, but they may help greatly with the readability of your code.
An infix function is like a named operator and can be called without dot and parentheses. The example from the documentation looks like this:
infix fun Int.shl(x: Int): Int { ... }
// calling the function using the infix notation
1 shl 2
// is the same as
1.shl(2)
Other example is for adjusting times. I like to define infix functions like
infix fun TemporalAmount.before(instant: Instant): Instant =
instant.minus(this)
Which allows me to write
val yesterday = Period.ofDays(1) before Instant.now()
instead of
val yesterday = Instant.now().minus(Period.ofDays(1))
There is no analogous concept in Java. As explained in the official documentation It just allows you to call the function without the . and () making it cleaner and less verbose. For example:
infix fun Int.shl(x: Int): Int { ... }
// calling the function using the infix notation
1 shl 2
// is the same as
1.shl(2)
As you can see this doesn't solve anything that can't be solved by a normal function call. It is just syntax sugar.

Kotlin: Spread operator on calling JavaScript method

I try to write a type-safe wrapper for a JavaScript library.
I need to call a method from JavaScript with variable arguments
(e.g. method(args...)).
The Kotlin fun for this should work with variable arguments, too.
Because Kotlin supports a spread operator, I tried to use it, but Kotlin do not want this.
Example code:
val jsLibrary: dynamic = require("library") // library given by node's require here
fun method(vararg args: String) = jsLibrary.method(*args)
Edit: Forgot to write spread operator '*' in code already. Compiler returns error because of the spread operator.
The Kotlin compiler returns the error "Can't apply spread operator in dynamic call".
Any ideas how to implement a wrapper like this, or do I need any workaround?
Thanks for your help!
Use external fun with #JsModule annotation
#JsModule("library")
external fun method(vararg args: String): LibraryMethodReturnType
This will do require("library") for you under the hood. You'll have proper Kotlin types instead of dynamic right away. You'll have no "wrappers", meaning no extra JavaScript call at runtime.
There is a hacky solution if for you want to manually use require and dynamic types: use apply method to pass all the arguments as an array.
val jsLibrary: dynamic = require("library")
fun method(vararg args: String) = jsLibrary.method.apply(null, args)

How to override any operator if the first operand isn't your object

I gave Kotlin a try, because it's supposed to be a java without certain limitations like checked exceptions or no support for operator overriding (of course these limitations got their right to exists, like reduction of abusing or forced verbosity, but this question isn't why they should (not) exist). So I wrote a simple Vector2 class, which should support basic operators like +-*/.
There isn't a problem when your first and second operand both are from the type Vector2, but there is a problem when the first operand isn't from type Vector2. Take this example:
fun main(args: Array<String>) {
val vector = Vector2(2.0, 3.0) * 2.0
}
This works flawless because of this method in Vector2:
operator fun times(d: Double) = Vector2(x * d, y * d)
But what am I supposed to do if the two operands change place like this:
fun main(args: Array<String>) {
val vector = 2.0 * Vector2(2.0, 3.0)
}
I though of an operator overload of times() for the type Double:
// In 'Vector2.kt'
operator fun Double.times(vector: Vector2) = ...
but I don't know how to retrieve the double value to multiply it with the vector.
Could anybody help? Thanks in advance!
When you define an extension function, the receiver (the object the function is called on) is always available as this, in the body of your implementation.
operator fun Double.times(vector: Vector2): Vector2 = vector * this
You could implement that any way you'd like, I just reversed the operands to shorten the example.

Why the literal "-9223372036854775808" (min 64 bit signed integer) is not accepted by kotlin?

I'm trying to write a fast json parser for JVM in kotlin.
And I found this issue, I'm not sure this is a bug or any good reason behind this.
val x: Long = -9223372036854775808L // compile error
this is marked as a bug in kotlin KT-17172.
as you can see the stdlib using the code as below:
public const val MIN_VALUE: Long = -9223372036854775807L - 1L
are you remember unary operator - in kotlin? if you divide the MIN_VALUE into special parts you may see it clearly. for example:
val x: Long = -(9223372036854775808L);
// ^--- the value overflow since the MAX_VALUE is 9223372036854775807L