Are namespaces coming to Kotlin (on JVM) soon? :st...
# announcements
a
Are namespaces coming to Kotlin (on JVM) soon? 😛
m
what would be their advantage over packages?
a

https://youtu.be/0FF19HJDqMo?t=418

as a solution to this: https://youtrack.jetbrains.com/issue/KT-11968
n
is anyone discussing namespaces as a solution to that?
I don't see the connection immediately
a
Well, Roman is.
n
I see. I guess around this point, namespace vs static is starting to feel like quacking like a duck but refusing to admit that you do, in fact, have a duck
t
They may work the same but they’re very different in terms of what the language syntax implies. A Class is a data structure that provides contextual behavior. Creating one solely for the purpose of housing non-contextual behavior is suboptimal. A namespace is a grouping of top-level referable objects. By nature they can/should contain non-contextual behavior.
I prefer languages that let me achieve a goal by expressing my intent rather than working around the language.
4
n
@Tyler Hodgkins not sure if I followed but the issue in question (that Roman suggested namespaces as a solution for) is entirely about finding ways to allow users to add the syntax <type>.foo to types they do not control
this isn't anything like the C++ idea of a namespace
those are obviated by packages, as Matteo suggested
Maybe to help further clarify this point (since it seems like the original question asker has been confused by it as well), if you look at the linked talk at 12:11, the namespace under discussion is something that would be used inside a class
it's not a top level construct
a
Yes, it can be both, look at 9:30
n
9:30 is blank
a
I mean play from 9:30
n
but ok, assuming you mean 11:49
a
No, watch from 9:30 onwards
n
I did, but we're talking about code, it's easier if you reference the exact code in question
a
It's important to listen to what he's saying as well
n
I did....
a
Okay so then you can see, it can be both, top level and inside a class
n
That is true, I shouldn't have said "entirely", but it does not change the fact that namespace inside the class is identical to
static
a
I think that's where there's a difference. When you declare an object, it creates a static instance of that object as well, you'll see this when you check the bytecode.
n
I don't understand, how is that different
In Java,
static
doesn't create an object. and the whole point of
namespace
inside a class is to have functions accessed via <classname>.foo without having any associated static object instance
a
You're right, in Java, static doesn't create an instance. In Kotlin, object creates an instance. That's why namespace would be the real static substitute, sort of.
n
yes, hence:
namespace vs static is starting to feel like quacking like a duck but refusing to admit that you do, in fact, have a duck
as far as "top level grouping of objects" goes, namespace may have some niche use cases, but in Kotlin, that entity is already the package. Java does not support functions at top level.
a
So you're saying just call it static?
n
I'm saying you may as well.
It's also a curious backpedal, after Kotlin was very adamant about not having static
a
Sure. That wasn't really my argument in the first place. I wanted to know whether this feature was coming. Call it static or namespace, lol I don't care about that. They were?
t
If you do that, the language is now less composable. You have an arbitrary
static
keyword that represents a method defined inside of a class that isn’t actually a method, it’s now just a non-contextual function. That
static
keyword can’t be used outside of a class (because it’s unnecessary).
n
the companion object thing I have kinda mixed feelings about, the language is making it easier to do something by using something that people should typically be avoiding (globals)
static is actually a lot more innocuous than companions in that sense
t
Why would they add a brand new keyword
static
when the concept they came up with (
namespace
) can represent the same thing?
n
I didn't say "it's important to call it static"
I'm just saying, this is very obviously static repackaged slightly
Kotlin's argued against having static in the past
t
And thus the point -
static
is arbitrary,
namespace
is generalizable.
n
I don't know what you mean by "arbitrary" here, other than, it's not a great name intrinsically, though it has the benefit of familiarity
t
“arbitrary” in the sense that it is solving a one-off use case, whereas alternate solutions can solve a broader set of use cases in addition to this specific case.
n
well, it's 2 use cases vs 1 use case
it's not a significantly broader set
I think both use cases look extremely specific though, and not very compelling. THe main place where it actually looks interesting is in generics, that's one of the few places where static is actually massively useful in C++
t
Well, if namespaces themselves can be nested it’s a third (something I’ve been looking for to help w/ a DSL that needs top-level referenceable definitions that need nested qualifiers to make sense)
n
That said I don't think Kotlin's generics system will allow any mileage from this anyway, at this time
I guess I'd have to see some concrete examples of the benefits it brings beyond making things look a bit prettier
I think it boils back to: a top level grouping of stuff is already handled by packages
👍 1
t
That’s true, but packages are very heavyweight, are they not? Namespaces as language syntax is much more convenient to define. I will agree - it could be a big departure from existing semantics in that case.
n
packages are not heavyweight at all
modules, yes, are heavyweight
FWIW I don't know of any language, at present, that has both in the kind of sense we're talking about
t
Well, to me a single package-per-file = heavyweight.
n
C++ and C# both have namespaces, not modules (C++ is getting modules, but this is all for historical reasons, because namespaces in C++ are a joke)
and most other languages have modules/packages but not namespaces
to allow referencing things as <something>.foo, a more obvious approach to me seems to just extend how imports work a bit in kotlin, more similar to python
where you can write simply
import foo
and then
foo.bar
, or even
import foo as f
and
f.bar
etc
a
I don't think packages are heavyweight from the compiler or from a runtime perspective. Correct me if I'm wrong.
n
no, they are not, Tyler means that the fact that they have to be in their own file is a bit "heavy"
I don't disagree completely with that, but it's just that the utility of this feature looks very low to start with.
I guess I'd like to understand, to start with, why people want to be able to write <whatever>.bar to begin with instead of just
import x.y.bar
and then calling
bar
FWIW C++ has both namespaces and class static functions, and class static functions are very rarely used, usually only related for things related to access control, and generics, both of which don't seem applicable here
n
Kotlin already has a module system: https://kotlinlang.org/docs/multiplatform.html
e
@Nir I guess I'd like to understand, to start with, why people want to be able to write <whatever>.bar to begin with instead of just 
import x.y.bar
 and then calling 
bar
People want it when
bar
is a short word that would be ambiguous without a qualifier. Just one example (there are tons more in libs out there). Take a look at
<http://Dispatchers.IO|Dispatchers.IO>
from coroutines. You don't want to write just
IO
as it is too short and lacks context. You could solve it by giving it a longer name with a prefix like
DispatchersIO
. But this way you cannot logically group all the dispatchers, all you'll have is their common name prefix.
t
e
F# modules is the same concept as Kotlin packages and the proposed Kotlin namespaces, with the latter (namespace) being essentially just a finer-grained package.
We cannot use the term
module
for this concept in Kotiln, though. It will be too confusing in the Kotlin ecosystem.
n
@elizarov rather than introduce a whole new concept of namespaces, why not slightly extend the capabilities of import, a la python? Allow importing packages and then you can use qualified names
1
import foo; foo.bar where foo is a package
I was actually a bit surprised when I started using Kotlin and saw this wasn't supported
Can also support as, e.g. import foo as f, f.bar etc
e
It is not about imports, it is about declaration. Currently packages in Kotlin are too heavy-weight (you need a separate file). Anyway, we don't have to introduce a new concept. That's still an open design issue. For example, we can name this concept "local packages". Nothing new, just lighter-weight syntax for declaring packages.
P.S. W.r.t Python-style imports. They are cancer. They lead to conceptual fragmentation of the language. In Python different groups of people use different conventions on what name to use when importing common packages, which makes it harder to understand Python code that you did not write. In Kotlin we follow designer-naming approach. That is the name of various things as they will appear in the source is defined by the designer of the corresponding API.
1
m
Good point on python imports, although they’re cool.
n
@elizarov I dunno, that seems a bit harsh
it's no different than a type alias, which I am free to declare myself, and name myself, whenever I want
Copy code
import kotlin.collections.List as foo


fun main() {
    val x: foo<Int> = listOf(1,2,3)
}
or there's this, already legal kotlin
it's really just consistently extending the same mechanisms to packages that already exist for classes, functions, etc
at any rate in a language with goto definition assumed, I don't think it's really a big deal, you just jump to the definition
I agree some kind of "local package" syntax plus simply allowing
import kotlin.collections
(without the
as
) seems to solve one of the two use cases. But there's still the other use case, where people really badly want to qualify using the class name. I'm not sure how much separate value that has.
e
The key question here is design intent and the actual practice. The intent of renaming imports in Kotiln is to address those rare cases when you have a name clash in your scope. And they are mostly used for that purpose (which is great!). I don't know what was the original design intent behind Python imports, but the way they are used in practice just fragments the Python ecosystem into various fractions with different imported package naming policies. If we were to introduce named package import into Kotlin, then what Kotlin problem it would solve? If you face such an issue, then please go ahead and create YT ticket and describing the problem you are having. We'll see how we can help you solving it.
n
I admit it doesn't solve any vital issue; I mostly thought of it because python allows it and I thought of python when this whole issue came up because python does allow `import kotlin.collections``
FWIW I write a lot of python and I don't think this is anywhere near as big of a deal as you're making it out, the overwhelmingly style in python is actually to do
import foo
and use
foo.bar
, or
from foo import bar
, renaming imports are relatively rare, or sometimes they are renamed to
_
versions (because pythons imports are transitive, unlike kotlin), and there are some standard aliases like
import numpy as np
But I also agree it's not all that valuable
I also don't think the original problem here is very important though, this wouldn't be on my top 10 probably even
e
Please, don't take it this way. I love Python, too, and this is not a big deal. It is just an observation. In fact, the style of API design of Python had already incorporated this feature. It is customary in Python to design APIs with very short top-level names, expecting that all the users will use named-package import to qualify them.
n
Don't worry, I'm not taking it that badly, I see your perspective 🙂 Actually Kotlin is really the language that has really cemented for me a lot of the problems in python's design, readability wise, so I think Kotlin has done extremely well.
e
We also want to allow this "qualified short-name" API design in Kotiln, but without a user having to pick a qualifier. That's what we already do with
<http://Dispatchers.IO|Dispatchers.IO>
,
Delegates.notNull()
etc. Unfortunately, right now we have to abuse
object
for that (which we don't need)
n
IMHO, a good enough first step is to just allow
import kotlin.collections
, it's a miniscule change and lets designers do what they want; a second step would be allowing a local "sub-package"
e.g.
Copy code
package top

...

local package sub {
    ...
}
And then
Copy code
import top.*

sub.whatever
Or
Copy code
import top.sub

sub.whatever
i'm sure though you've already discussed this and many other options though
a
@elizarov do you think it's a big deal that declaring an object creates a static instance of that class as well and there's no way to avoid it (personally, I don't think so but curious to hear your thoughts)?