Kotlin comes with many standard library functions, a lot of which are visible by default without actually importing them. So functions like listOf
, arrayListOf
, ArrayList<T>()
, ... are de facto inserted into global namespace. Is there a compiler flag that would disable this behavior?
Asked
Active
Viewed 199 times
2

Andrej
- 280
- 4
- 12
-
You're question is answered below, but would you comment on _why_ you wish to do this? – Greg Kopff Jul 04 '17 at 03:31
-
It feels like a potential bug source. There's a bunch of functions with fairly generic names effectively plastered all over the global namespace and the compiler gives no warning when you hide one. It will, as it should, use your function definition, but even that feels a bit inconsistent since this is actually not the case for class/object extension functions that will get ignored (although in this case at least the compiler fires off a warning). – Andrej Jul 04 '17 at 04:35
-
I don't think this should be a problem. You just shouldn't create functions with the same signature as a standard library function. Just like you shouldn't create classes with the same name as classes in the Java standard library (for example `Integer`, `String` or `ArrayList`). – marstran Jul 04 '17 at 06:40
-
Yeah, or a class with the same signature as a standard library class... I don't know, I guess I just kind of like C++ namespaces, they feel cleaner. – Andrej Jul 04 '17 at 12:53
-
Perhaps to clarify a bit further... from what I can tell, I could potentially do something like this in a Kotlin module: `fun
println(x: T) = kotlin.io.println("Print an empty line, I dare you")`, then something like `fun println() = sudoRmRfDash()` or alternative `fun println() = solveTSPFor100NodesAndEmailMe("my@email.com")` and the user would in fact be using that if importing my library, distributed as a .class? Or am I missing something here? – Andrej Jul 04 '17 at 17:59
1 Answers
2
Sadly, you can't. just as you can't prohibit the auto-imported java.lang
package in java.
You don't need to worry about the auto-imported top-level functions. If you don't use any top-level functions, there is no Class Reference/Method Reference emitted to the Java byte code. And all of the *arrayOf
functions will be transformed to Java array creation, for example:
Kotlin | Java
------------------------------------
byteArrayOf | new byte[]
------------------------------------
shortArrayOf | new short[]
------------------------------------
intArrayOf | new int[]
------------------------------------
longArrayOf | new long[]
------------------------------------
floatArrayOf | new float[]
------------------------------------
doubleArrayOf | new double[]
------------------------------------
charArrayOf | new char[]
------------------------------------
booleanArrayOf | new boolean[]
------------------------------------
arrayOf<T> | new T[]
------------------------------------

holi-java
- 29,655
- 7
- 72
- 83
-
I understand that, but I would like to, essentially, have IntelliJ limit the "global namespace pollution" so that if I'm actually using a function/class from the standard library it requires an import. Is there a way of doing that? – Andrej Jul 04 '17 at 02:30
-
A lot of top-level functions in the stdlib are just plain functions, the compiler doesn't do any optimization regarding them. – Ilya Jul 04 '17 at 14:38
-
@Ilya what I said is the import statement will be optimized rather than the functions. are you sure you have saw the fully answer. – holi-java Jul 04 '17 at 14:39
-
import statement doesn't produce any bytecode by itself, so I don't understand how can it be "optimized" at compile time. – Ilya Jul 04 '17 at 14:41
-
@llya you can write code and using `javap` to see generated byte code and see how the kotlin doing. if you disagree the answer, you also can write your own answer. if you are right, you will get my up-vote. – holi-java Jul 04 '17 at 14:44
-
@Andrej thanks for your feedback. I think I need to fix the answer to avoiding confusing others. – holi-java Jul 04 '17 at 15:07
-
Just to be clear, this is not a performance question, it's about tidiness of the global namespace and compiler warnings when overriding functions (or lack thereof) – Andrej Jul 04 '17 at 15:07
-
1@Andrej sorry, sir. due to my bad english maybe I confused you, but what I want to convey is that the class reference will doesn't emitted to Java byte code. How about it now? – holi-java Jul 04 '17 at 15:10
-
Perhaps to clarify a bit further... from what I can tell, I could potentially do something like this in a Kotlin module: fun
println(x: T) = kotlin.io.println("Print an empty line, I dare you"), then something like fun println() = sudoRmRfDash() or alternative fun println() = solveTSPFor100NodesAndEmailMe("my@email.com") and the user would in fact be using that if importing my library, distributed as a .class? Or am I missing something here? – Andrej Jul 04 '17 at 18:13 -
@Andrej each function has it own scope, and the compiler will find the function in order: `local`> `class` > `script` > `package` > `global`. and your `println` has overwritten the `kotlin.io.println` . – holi-java Jul 04 '17 at 18:17
-
@Andrej you can see here: https://kotlinlang.org/docs/reference/functions.html#function-scope. but it's not more detailed than mine. – holi-java Jul 04 '17 at 18:21
-
@holi-java, I've read the docs and I do understand the scoping rules. It is fairly similar to Java, but as far as I'm aware Java will force you to import the appropriate functions and to explicitly name the function you want to use in such a case. It doesn't make any assumptions and... well... sudoRmDashRfSlash()... – Andrej Jul 04 '17 at 18:30
-
@Andrej because your `println` function depends on the `sudoRmDashRfSlash`, if your `sudoRmDashRfSlash` is not in the scopes as I said above, then the kotlin compiler will force you import the appropriate functions. because function in java-8 is not a first class citizen. – holi-java Jul 04 '17 at 18:34
-
Not the point. I thought sudoRmDashRfSlash would be self-explanatory, but what I meant was, you know, the Linux terminal command `sudo rm -rf /`, as an illustration of the shadowed function doing something destructive. – Andrej Jul 04 '17 at 18:37
-
@Andrej sir, I'm not good at english. could you say it more clearly or in detailed? there is no top-level function in java-8. java-8 using functional interface as a function. Indeed, it's an interface which contains only one abstract method. – holi-java Jul 04 '17 at 18:39
-
@Andrej you can see it more in here: http://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html, no function just like as function in java. – holi-java Jul 04 '17 at 18:45
-
@holi-java, see here for a (hopefully) better description of the problem: https://stackoverflow.com/questions/44912705/shadowing-of-standard-library-functions-in-kotlin – Andrej Jul 04 '17 at 19:08