Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid using vararg in API #30

Open
altavir opened this issue Dec 8, 2019 · 11 comments
Open

Avoid using vararg in API #30

altavir opened this issue Dec 8, 2019 · 11 comments
Milestone

Comments

@altavir
Copy link

altavir commented Dec 8, 2019

Both because it complicates function calls, especially when vararg is not the last argument. Also there is possible performance impact because of array re-wrapping in kotlin.

@dievsky
Copy link
Contributor

dievsky commented Dec 9, 2019

As far as I can tell, the only API methods that use vararg are also the ones where its use is unavoidable, like the general getter/setter methods. Which methods were meant exactly?

@altavir
Copy link
Author

altavir commented Dec 9, 2019

It is better to use IntArray for that. You can then add vararg extension on top of that. The problem with vararg is that when you need to pass thtough some arguments to setter from some other function, you need to use spread operator * and Kotlin usually allocates additional array on each spread call (it was the problem some time ago, but I am not sure if it was fixed). Also if you have signature like operator fun set(vararg indices: Int, value: Double), the only way to properly call it as a function is like this: set(value = 1.0, indices = *intArrayOf(2,3)), which is really inconvenient.

@dievsky
Copy link
Contributor

dievsky commented Dec 9, 2019

So you're saying that we should provide both IntArray and vararg signature? This does sound reasonable.

the only way to properly call it as a function

The vararg setter can be called in two ways:

  1. as an operator: a[1, 1, 1, 1] = 42.0, or
  2. as a function: a.set(1, 1, 1, 1, value = 42.0)

No manual spreading and array-creation is required in either of them. This probably should be explicitly mentioned in the KDoc, though.

@dievsky
Copy link
Contributor

dievsky commented Dec 9, 2019

Turns out we can't provide both IntArray and vararg signature, since they cause a JVM clash.

@altavir
Copy link
Author

altavir commented Dec 9, 2019

It is easily solved by @JvmName annotation. Even better - you can move vararg one to extensions. Here is the example.

@altavir
Copy link
Author

altavir commented Dec 9, 2019

About setter, you are correct. My problem was with this construct: f64Buffer.set(value = value, indices = *index).

@dievsky
Copy link
Contributor

dievsky commented Dec 9, 2019

I wonder why does the extension approach work, while defining the method inside the class does not.

@dievsky
Copy link
Contributor

dievsky commented Dec 9, 2019

f64Buffer.set(*index, value = value) looks a little better, though it doesn't solve the performance impact of wrapping and spreading.

@altavir
Copy link
Author

altavir commented Dec 9, 2019

Because extension is a static method in YourClassKt from JVM perspective. It is not in the same class.

@dievsky
Copy link
Contributor

dievsky commented Mar 12, 2021

Also, F64Array.full is not fun to use at all.

@altavir
Copy link
Author

altavir commented Mar 12, 2021

Not fun, definitely :)

@dievsky dievsky added this to the 2.0.0 milestone Nov 4, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants