Open mauro3 opened 9 years ago
there seems to be a mixing of terms here. importall
is explicitly doing the import of absolutely everything. it's target usage is really interactive development, where you don't really care about safety or conventions, but just want to try out an idea quickly. using
makes the exports available. import
is the safe option for listing exactly what you want.
No, I'm arguing that there should be a construct which only makes the exported variables available through the fully qualified dot-syntax. Reiterating above example, package A
defined like so:
module A
export a
a() = 1
b() = 2
end
now using this with, let's call it import_only_exported
for the sake of clarity:
import_only_exported A
# now only exported symbols are available with fully qualified syntax
A.a() # works
A.b() # ERROR: UndefVarError: A.b not defined
# none are introduced to the current workspace:
a() # ERROR: UndefVarError: a not defined
b() # ERROR: UndefVarError: b not defined
But it was maybe a bit confusing as I suggested both import
and importall
be modified slightly (in an effort to keep the number of keywords constant...).
The idea would be that import_only_exported
would allow to easily program with only the public API (i.e. what's exported) without having to pollute your name-space with using. I don't think that is possible at the moment but it may be of value?
If field overloading was allowed and ..
became the operator for direct field access (https://github.com/JuliaLang/julia/issues/1974), then I'd be in favor of making unexported functions available only using A..b()
.
But adding yet another variant of import
would only create more confusion IMHO.
The problem exists also when you are doing specific imports, eg
import A.b
works even though b
is not exported in A
.
I agree that it should be possible to import things in a way that protects you from importing an unexported symbol by mistake, also when using the more disciplined alternatives to using
. This is no simple fix though, and I'm not sure what could be a good solution.
Restricting access to A.b
seems to require some kind of access restriction as discussed in #12064, but coming up with a form of import that disallows to import A.b
seems more about coming up with the right syntax (which is hard enough, of course :)
I like @nalimilan's suggestion, if the ..
comes along.
Would it be possible to chain the private symbols. I.e. that in the initial example b
would only be accessible by A.A.b()
? I know that this might currently be a technical problem (since A == A.A
) but conceptually this could work
As an alternative to ..
, which other people have expressed a desire to use for intervals, IIRC, what about .!
. I think it is less accident prone (one vs two dots is harder to see), and more visible (exclamation points do grab your attention).?
I definitely want a way to be able to access the exported members – and only the exported members – using the module name as a namespace qualifier. This is to avoid PHP's massive global namespace, which leads to confusion as to what name comes from what module.
Ping?
This seems like a major problem for large-scale projects. Common Lisp solved it by separating a:b
(accesses only exported symbols in package a
) and a::b
(accesses any symbol in package a
).
Can I ask what is the status of this proposal? Is it placed in the roadmap (and in what shape?), rejected or still under discussion?
In case it helps.... the following Discourse comment provides and example of how to create private properties for a type.
My (maybe wrong) understanding is that the public API of a package is what its main module
export
s.However, exports only impact when
using
a Package and not whenimport
ing. However, for larger scale software projects it is probably often preferable to useimport
to get the safety benefits of separate name-spaces. But this means that when I program in the "safer"import
-mode there is no easy way to tell whether I use the public API or some private feature. So, it's not really safer at all.I wonder whether it would make sense and be more consistent with
using
thatimport
only allows access to the exported bindings, and thatimportall
imports all the bindings (and also allows method extension, i.e. as it is now):(this needs more working out though)
This would be a breaking change but could maybe be done through depreciation warnings. Worth the hassle though?
Or could/should one write a
@safeimport
macro doing above?Related: #8000.