# similar calls
include(file_name)
include_string(cur_string)
eval(parse(cur_string))
cur_parse = parse(open_file)
while cur_parse != nothing
eval(cur_parse)
# could also do something like:
# include_string(string(cur_parse))
cur_parse = parse(open_file)
end
One thing I’ve noticed for sure is there are different levels of error checking done between include and eval.
include and include_string go through basically the same code path and call jl_parse_eval_all, which loops over expressions one at a time in a JL_TRY block, calling jl_toplevel_eval_flex.
eval goes through jl_toplevel_eval_in first and calls jl_toplevel_eval_flex directly.
So two differences are: parse and open can throw directly, whereas include/_string call some lower-level i/o functions directly; and I think the while loop over expressions could surface errors earlier.
(I’d also suggest to read through the devdocs for some additional information and more grep keywords)
I’m not sure I understand the question – include from where? Wouldn’t that just be eval?
ccall.
(get cozy with grep, it is your friend – you can see many example ccalls into libjulia, including for some of the functions I mentioned above, in base/)
I figured as much… I guess what you want is to pre-parse all the files in a directory and do a dependency analysis to decide which file is a pre-cursor, so you can load that one first? Hmm. It’s kind of an interesting problem, but I don’t have a good suggestion right now. Maybe a minimal example would help, but if I think of something I’ll post again. Or correct me if I misunderstand what you want to do.
(I agree with all of the “what, why?” responses to Boot.jl but I’ll still try to answer your questions if I can grok them. I have strong reservations about encouraging people to actually use something like that, but as a learning exercise, knock yourself out )
You might be interested in reading about Include What You Use – they’re solving kind of the opposite problem: figure out what headers are not necessary for a C++ file (it’s roughly “what headers are already transitively included,” but there are some weird details and complications due to the preprocessor).
I’m not sure if there is a question, here so please let me know if I missed it!
FWIW, I would expect this to be fairly difficult, if it is possible. You probably need to really constrain the problem or do some semantic analysis and figure out how to determine ordering for minimal examples (like only type definitions). It’s not quite clear to me if the Boot package is trying to:
a. discover implicit file load-order dependencies? (there is a necessary internal ordering – you just don’t want to have to write it down)
b. eliminate ordering entirely (so anything can be defined in any file and Boot figures out what comes first – this sounds impractical to me. Are you aware of any other languages which do something like this?)
Doesn’t rails load everything? Or at least give you the means to efficiently load everything (simply):
edit: from that article, maybe they’ve constrainted the problem to be solvable. i will say though that i’ve had some success adding Boot.jl to PyCall, JuAFEM, Tensors, Gadfly, IJulia and Mocha (i.e. the tests pass)
Also to tie some stuff together, this is why I asked:
Neat - TIL! (I’ve only written a few lines of Ruby, ever, and it was last week trying to hack up something in Jekyll).
If I understand correctly, the constraint there is one-class-per-file, at least by-convention, which is probably a bit easier because every class is a unitary namespace.
Isn’t this effectively doing (a) in my post – discovering the file ordering which already exists by necessity of the design of “default code-loading” (because those packages were otherwise written without Boot).
Which is neat, btw! What I’m wondering is whether that’s the main goal. Clearly you’ve had success, so discover-ordering seems doable (it’s (b) that I think would be hard).
Think about the worse-cast complexity of unordered “shards”. Think about the semantics of commands with side-effects (it seems like the order would be essentially non-deterministic from load to load).
Each file reduces to a set of definitions (types, functions, constants) paired with a set of uses. The simplest comparator is “a given file’s definitions must come before another file’s uses” (assuming no methods are actually called during loading…).
In that case it seems much easier to just write the ordering down . Otherwise you and the loader are playing a weird game of telephone for uncertain benefit.
That page seems kind of circular to me. Basically it reads as:
“files” define a specific interface (a class for PHP; a function for IDL and older Matlab; a +x file for the Unix shell; etc.)
you tell your compiler where to find things (load path)
But by that definition, Julia and Python have auto-loading for modules (assuming you have your load path set correctly, of course). C even seems like it has auto-loading for includes (again assuming you’ve told the compiler where to look!).
In that case, for your loader or packages you could enforce a rule similar to IDL in that example (and older Matlab versions), which is “one global per file with matching filename”. Then the problem is easy. But that sounds really annoying to use (and it was really annoying in Matlab). Personally I would rather just write down the ordering explicitly, but I suppose it’s a matter of taste.