That’s all basically what we do in our CI already. But “design by CI” is an incredibly slow iteration loop. What ends up being the most useful for design iteration is something between a unit test and full integration test. So like targeted micro-simulations that only exercise the behavior you’re currently working on. Iinteractive exploration is important here as well, since test-based validation will only catch the things you thought to add metrics for. But a lot of the times some change you made might induce some funky oscillation that never actually exceeds any failure bounds but is nonetheless potentially concerning or at least worth watching. And outside of system validation, interactivity is just extremely valuable when debugging issues. Most things in dynamic systems can’t be debugged by looking at a single step of a simulation; you usually need to see things play out over some period of simulated time. All of this to say: there is definitely a need for running Rust from Julia in an interactive environment.
I neither love that idea. To clarify, I was thinking of this for development, as a workaround. I’m not up-to-speed on why you can’t just reload the new .so under same name.
Probably relevant:
The POSIX standard actually does not require dlclose to ever unload a library from address space:
Although a dlclose() operation is not required to remove structuresfrom an address space, neither is an implementation prohibited from doing so.
So a Linux limitation Julia just can’t get around, and would apply to any other language? Or (no longer) a problem in Linux and relevant operating systems?
[The renaming of .so files would not be ideal in production… yes, would you really need to reload them in a (running) production system? A very rare requirement I think, could be made to work.]
Julia can certainly be used in production, done by many. Easiest by Just using the source code of your project, or more likely copying the .julia directory (if the arch fits, for the precompiled code, it wouldn’t even fail if a different arch, just would precompile, I believe).
I’ve mentioned AppBuilder.jl to distribute, code to others conveniently. For Compiled apps (not needed on your own server) and/or with PackageCompiler.jl.
The tools we have do not rule out deploying something with Rust dependencies with them in JLLs should work, if not, probably needs some manual work, setup), but likely do not help or support Rust or binary dependencies either, when not in JLLs. PythonCall.jl though downloads package dependencies from Conda, including Python itself if needed. Autocratically. I guess something similar could be done (automatically) for Rust/Cargo (might already exist?).
juliac promises 1 MB binaries (or that is the fixed overhead). Is that any kind of issue for compiled production systems?
Is there any overhead (of Docker) you worry about (none for speed; except networking it seems, still?). Why is the Docker large? Only to begin with, and larger than say just the .julia? How large is it? Julia is 243 MB compressed, you should be able to get something of that magnitude without juliac for minimal code (plus the compiled code).
Julia just calls your libc dlclose, if the libc decides not to do anything there isn’t too much we can do about it (apart from implementing a whole new dynamic loader).
A big source of the difference between calling development actions is, obviously, that Julia is dynamic and the REPL typically plays a big role. Rust has no REPL, so something like cargo is really the only good choice. Using the binary-with-commands model. Similar to git and other modern(ish) tools.
But I don’t think developing cargo-like tools is fundamentally difficult. There is a solid packaging and dependency model to build on. A utility Ion tries to be a cargo-like utility for Julia. It’s written in Rust but still spawns Julia, so it has latency. Implementing some of these things purely in Rust might be convenient . (Or in some future, small, Julia binary) It would be lot of work and no one has gotten around to it.
How many characters you have to type is kind of a distraction from the important points: What kind of performance or latency does a command entail? Is it build on a solid and reliable packaging model?
I’ve found that testing in rust is often pretty fast. Especially parallel testing with stestr. But thats rather anecdotal and maybe particular to the projects I’ve worked on. However, if I change compiler version or between release and debug mode, then everything including dependencies has to be recompiled, which is very slow. I wouldn’t be surprised if there are some workflow tricks to make this easier.
Small correction, evcxr. Never used it myself so I don’t know how it works with an AOT-designed language, and I’ve read muddled disappointments with its performance in passing. Though looking at the summary of how it works, I wonder how much of that is just people discovering the joys of compilation latency at runtime or forgetting about the mitigating default to debug mode. It also mentions another REPL project IRust with the advantage that “you can have variables reference other variables,” but “all your code gets rerun each time.” Both projects also have Jupyter kernels.
The point I have been trying to explain, and I will explain again because it is worth understanding this:
in some environments/applications/domains the REPL is not used, it does not exist (or more accurately it cannot be used)
Forget about the REPL, for now, or at least consider it as an optional thing. Julia is not the same as the REPL. In some contexts it doesn’t exist.
I know that for some domains, the REPL is of critical importance. I used to work in research Physics and I still sometimes do data analysis work with Python/Julia using either the REPL, or Jupyter notebooks
Consider this example:
You write a webserver in Julia which hosts a website. (The exact example doesn’t matter.)
You copy your Julia code to a server somewhere.
How are you going to start it running?
You cannot login to the server, start the REPL and run your code from there. As soon as your ssh connection exits/breaks/disconnects, your REPL is gone, and your website goes down. You are not going to maintain an “always on” shh connection to the server. You are not going to leave your laptop open and connected to it forever to keep it alive.
To start it up again, you would have to repeat the process. This isn’t how servers are set up to work. They do not require people to babysit them 24/7.
Instead, you are going to write a short script (maybe a combination of bash and systemd on Linux) and you use that script to configure Linux to run your webserver automatically.
Alternatively, the more modern solution is to install Docker, containerize your application (which just means create a Docker image containing your code) and configure Docker to manage running it instead of systemd.
I think you are basically looking for functionality that is not mature in Julia. Compiling to standalone executable, while doable, has not been practical or ergonomic. It’s mainly a language one uses from the REPL, and the tooling and infrastructure (including Pkg.jl) reflects that.
Support for standalone executables and libraries is a work in (quite active) progress, and the infrastructure will develop around that. Your complaints, while not unreasonable per se, is basically that it’s “not done already.”
Of course deployment of standalone executables is not smooth, when the static compiler is still experimental, and most of us don’t even use it anyway, but work with the REPL.
So when I said that Pkg is really good, it is from a REPL-centric perspective.
Yes exactly. I was replying to one of the previous posts which seemed to suggest there wasn’t a way to run foo.jl without loading the REPL. That was my only point there
What is the advantage of it integrating with the REPL? I haven’t yet understood what the advantage of this is. It might be because I don’t primarily use the REPL for the work I’m doing at the moment.
I guess if you don’t happen to have a package installed, and you need it, it’s perhaps useful not to exit the REPL and lose the state?
In many use cases one builds the environment on the flight, experimenting different things, trying new packages. It is just super convenient to have this integration. As, in general, having a REPL for interactive development.
For me, the REPL is the universe within which I work. I call all the code from within it, exploring the data, plotting from it, etc. I write complex codes in an editor, but everything is centered around the REPL.
And then having tight Pkg integration is essential.
We have all been thoroughly aware of this and of its implications for years. In order to make a clear argument, It’s worth repeating when laying out a specific scenario, as you did in the example of the web server that you gave. But, as I said, everyone here with a bit of experience has a very thorough understanding of basic facts and of their implications.
And, in case it wasn’t clear from my post before, I think having leaner, faster tooling around Julia that is free of the REPL (and compilation to the extent possible) would be a great thing. My point was that, barring curiosities, it’s the only option for Rust, which is why such tooling is more developed in Rust than it is in Julia.