-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
relative using/import should search current directory #4600
Comments
I agree it should not look in the global places, but perhaps it should not look at files at all. This doesn't seem to extend to multiple dots, e.g. |
Oops. |
I would love to see a solution to this problem... But Jeff has a point. Would be a little weird, but what if
|
+1 for this. |
I'm not sure the relative path thing is a problem. You could, for example, have something like # Foo.jl
module Foo
using ..Bar
using .Baz
end # Bar.jl
module Bar
# barfy stuff
end # Foo/Baz.jl
module Baz
# bazish stuff
end That would allow relative imports of sibling modules to automatically work. Sure, it's strange if you do more dots than you're nested into modules, but just don't do that. |
Why just not allow to use |
Because loading from a file is only a side effect of using when no such module exists. The normal case is that the module already exists. If you allow a string, you still have to map those strings to a module. |
But if the string, which is a path, qualifies a module, which it does due to its structure? |
Ok. Let me try to get this straight. I do not have an opinion about this "import/include/using" oddity. Don't you think that sooner or later, the python import strategy turns out to be best? I ran into exactly this problem, that I arranged my code in a file directory manner and tried to Let's just presume I know what I really liked the import idea of Java. Where dots marked a directory. For instance:
or
Does this make sense to you? Cheers Stefan |
Bump. Milestoning. #9079 (comment) |
It's a little frustrating to have #12695 merged in 0.4 but this slated for 0.5... I feel like it's going to bite people in 0.4 if there is no way to load modules from the current directory short of modifying the load path. |
We seem to have been getting by pretty well without that --- outside of the REPL, loading from the CWD is just a bug, and I doubt any packages depended on it. In the REPL, |
I used to structure my code into submodules, with each file representing a module ; back when the CWD was included in the load path, this allowed me to use for instance |
I have hit the same problem as @bermanmaxim FWIW, and I've moved to just |
Thanks @IainNZ. Using |
You can use |
I still don't fully understand what this feature should be in the first place. So ignoring the syntax possibilities and just using the quotes to denote this new feature (despite me not liking the quote syntax it's the easiest way to talk about it for now), how should it behave? In terms of current functionality I think we're all fairly consistently talking about
I'm not as clear on I'm also not clear what this means outside of the context of a single package's implementation. Given a package
Is there desire to detangle |
this depends on whether foo(x) = x
module File
end
the globals in package module is evaluated at
depends on which we implement, for the first one, there is no file modules, for the second,
I think
if we go with the implicit file module then yes, if not then no. |
Oops, I messed something up: my daughter came into the room and started talking on her phone. My voice recognition picked it up and now there is a message above that I "unassigned" some core devs! Sorry! No clue how to fix it. |
No problem, I reassigned myself. |
Assessing stability and whether or not a package will be maintained can not be done by looking at either the number of github stars or when they were last updated. UnPack.jl, as an example, has few stars, but 70 direct dependents and 878 indirect dependents in the general registry. It's an excellent package for what it's doing and will likely remain an excellent package for a long time. This is a common occurrence in the Julia ecosystem, small packages that do one thing very well does not need to be updated (no bugs to fix, no features to add), and many may feel they are so trivial and often used as to not warrant a "bookmark star". |
Reflecting on
|
I very much look forward to this review document and package! |
@StefanKarpinski asked for some people to start using a system of concrete language proposals with this issue as a starting point. I want to pitch in, though I don't have all the background on this issue. I can write up some things about Python's system since that seems to be the most-discussed implementation here. It would be nice to have some more "foreign language" perspectives. @Roger-luo would you be willing to turn your understanding into a mini package that captures one of the possible implementations so we can discuss it concretely? Or is there nothing else to add on top of FromFile.jl, that can be done without altering the parser? I tried to do it myself but afaict it's not possible to write this |
@adkabo We have written a proposal and an implementation but it's not people's favorite IMO the implicit file module is the key of Python module system as far as I understand which is FromFile. If you want to do exactly the same as Python then you only need to let the implicit module name to be the same as file name instead of a mangled name. so I proposed several alternatives (not all implementable as an external package tho) but no one add thumb up to the alternative I proposed so I assume all these are not favored. I'm not sure if there's actually a revise comment on our proposal, most comments (exclude proposal authors) above seems to just against adding this feature. So I'm also not sure what to revise for the original proposal. I'll leave it for other people's idea for now unless I have something better in the future. |
Here is a close to trivial implementation of my suggestion (which is essentially identical to this one made back in 2013). I guess it's a bit impolite to operate on source code instead of Expr trees, but given that the arguments to the using statement do not parse as "regular" Julia code this is by far the easiest way to support the full syntax. Note also that this is completely unchecked and unsafe, it's really just a proof of concept (it is also quite likely that it contains numerous errors - I really only tested the most basic use cases). using MacroTools
function using_expr(args)
str = ""
for a in args
str *= " " * string(rmlines(a))
end
esc(Meta.parse("using" * str))
end
macro rusing(path, args...)
quote
pushfirst!($(esc(:LOAD_PATH)), joinpath(@__DIR__, $path))
$(using_expr(args))
popfirst!($(esc(:LOAD_PATH)))
end
end As you can see it implements a macro @rusing "." MyLocalModule To load a module in a directory "../modules": @rusing "../modules" SomeOtherModule The full using syntax is supported, so these should work: @rusing "." M1, M2
@rusing ".." M3 : function_with_a_long_name as fun1 Needless to say, exactly the same thing could be done for Compared to some of the other suggestions that have been made, this one
For me at least this would solve the one major annoyance of the current module system. I actually wouldn't even mind just using this macro, but unfortunately it's impossible to import macros from a module without language support (AFAICT) so it will always lack functionality. |
This is literally me right now (coming from javascript/es6, Go, Python, ...). I really love what I've seen from Julia so far, expect this. |
As someone working on a large production codebase (well into 1000s of LOC) in Julia, I can safely say that this issue single-handedly is my biggest gripe with Julia in prod and the reason why I would never use it myself if I had the choice. Huge amounts of code are needlessly recompiled in the tests which defeats the whole philosophy of Julia being a fast and efficient language where you only compile what you need. While some aspects of the codebase are in theory different/logically separate from each other, in practice they would only ever be used with each other. So the point about having loads of different packages is irrelevant in my case. It would be an unnecessary organizational headache to have to have these as separate packages, either with git sub-repos or possibly with different repos altogether. I really like the idea of Julia and there are lots of things about the language I like but this massively discourages usage in industry, which discourages usage in general. If you want Julia to be more widely adopted, having the ability to load code once/efficiently from your own package would be helpful. It doesn't force anti-patterns on developers, but forcing people to separate coupled or helper functionality into its own package for the sake of not recompiling it 10s or 100s of times certainly seems like an anti-pattern to me. |
What does this issue have to do with repeated compilation? |
I'm not sure what you're referring to specifically in that question @StefanKarpinski. If you're asking about the being fast/efficient language where you only compile what you need, then the answer is that it's hard to be fast or efficient in a more holistic sense if the language/loading infrastructure forces you to load internal package code every time you use it, potentially 10s or 100s of times. This is especially true of tests if you write test files as independently runnable files. |
I think OP is doing
which causes re-compilation of methods since the two OP please look at |
If that's what you're doing, @danielsoutar, then don't do that—except in unusual situations you should not be including the same code multiple times, you include each file only once. This issue does not affect that. Feel free to ask questions about the right way to use Julia features like |
just want to show some numbers here one year later, despite a few people against the proposal I had with @patrick-kidger a while ago in https://github.com/Roger-luo/FromFile.jl and this also answers the question @ChrisRackauckas asked at some point that if a feature really necessary for people, it should be implemented as a package and we can tell that from the number of users. On JuliaHub the FromFile package had 1.1k new users in past 30 days, and for reference Pluto has 5k new users in past 30 days. I believe this means something and worth everyone involved in this issue to think further. |
My two cents: this has been an absolute game-changer for the codebase I'm working on and my team can now flexibly load modules in files where needed without suffering performance penalties. People shouldn't be forced into a C-like project structure from the 1970s where files need to be arranged to minimize I define things in some modules, with (optionally) a module per file, and these modules/files should be transparently referenced by the code in every file that uses them. Like helper functions, common types or data. Now I can run individual test files without modification. I seriously encourage people to try this in any non-trivial package and see the benefits for themselves. Thanks to @Roger-luo and @patrick-kidger for this. |
At the beginning (few years ago), I also thought that the provenance should be explicit. Now that I use LSP within kate, And with respect to python, I like the ability to split modules into several files with So it is good that your work style is taken into account, but I also like the current design now. |
@ederag i feel like you prioritize not scrolling more than many, perhaps most, would. |
When I do
and there's a file called
Foo.jl
in the same directory asMain.jl
it should be loaded. I suspect that relativeusing
should also not look in the global require places – i.e.Pkg.dir()
and thenLOAD_PATH
. The same applies toimport
.The text was updated successfully, but these errors were encountered: