A “shared” environment is simply an environment that exists in ~/.julia/environments . The default v1.8 environment is therefore a shared environment.
Shared environments have a @ before their name in the Pkg REPL prompt.
Is there anyone who can tell me what’s the essential difference between a “shared” environment and a general one, and when should I use a “shared” environment?
I think the most salient difference is that you can easily activate a shared environment without memorizing the path to a particular directory. Normal environments are activated by referring to their filesystem path, i.e., julia --project=/path/to/environment (though usually you’ll cd into the directory and run julia --project=.). Shared environments can be activated as julia --project=@name regardless of what your current directory is.
I currently have one shared environment in addition to @v1.x. I call it @scratch, and it contains packages that come in handy for quick, disposable analyses and plots in my day-to-day. That way, I can run julia --project=@scratch from any folder and be ready to go if I want to make a quick plot or benchmark et cetera. I’ve also installed an IJulia kernel that launches julia with @scratch activated, so I can just as easily open a scratch notebook anywhere.
The packages installed in @scratch reflect what sorts of one-off things I’ve been doing over the last several months. Currently, the list is:
The base environment @v1.x is always present in addition to whatever other environment you’ve activated, unless you jump through extra hoops to avoid this. Therefore, it’s recommended to keep @v1.x minimal and only use it for packages that you want to have available anywhere, and that don’t really belong in any given package or project environment. For the most part, that means developer tools—things like Revise, BenchmarkTools, ProfileView, IJulia. My current list is:
Note that by installing MKL in the base environment and putting using MKL in my ~/.julia/config/startup.jl, I’m able to select MKL as the BLAS/LAPACK backend globally on this machine. This is another example of something that I always want on this computer, but that is not the business of any particular package or project (imagine I share a project with a friend who’s on Apple or AMD hardware—I definitely don’t want the project itself to have an opinion about which backend to use).
Now I still have a question: The packages installed in the base environment @1.x or other shared environments such as your @scratch can also be used in any other customized environments, can they?
No, the default load path is such that the first place to look for a package is the currently activated environment, then the @v1.X environment of your Julia version, then the standard libraries of this Julia installation. The environment @shared would not be found, although you can in theory mutate your load path variable and add it to the stack. That’s usually not a good way to do things though. Best is to keep the local environments clean and specific to the task you need them for. And leave only essential tools you always need but which don’t carry tons of dependencies themselves in the @v1.X env.
No, shared environments are not included in your load path unless you activate them explicitly. In this sense, they behave the same as regular environments. The only special thing about shared environments is that you can activate them by name instead of path—in every other sense, they work like your regular environments.
The exception is the base environment @v1.x, which is always available unless you take specific steps to remove it from the load path. This is where you can put packages you want to always have available. See Code Loading · The Julia Language.
You can in principle muck around with the load path to achieve arbitrary environment stacks (see the documentation for LOAD_PATH and Base.load_path), but environment stacking is brittle and rarely a good way to organize your workflow. In particular, the loading of dependencies does not respect environment boundaries, so you may end up loading incompatible versions of packages. Imagine you stack NewEnv on top of @scratch and @scratch contains package A which depends on package B version 1, while NewEnv contains package B version 2. Now you can do using A to load A from @scratch, but when the code in A does using B, the version of B that gets loaded is the one in NewEnv, which is incompatible with A. This is one of the reasons it’s a good idea to keep the base environment minimal and only use it for the packages that help you develop and work with your code, rather than the packages your code actually relies on to do its job (for example, create plots).
In short, if you want to use UnicodePlots within NewEnv, then it belongs in NewEnv.
How does any of this change if I am using VSCode instead of the REPL? In particular I often start Julia by going ‘Shift+Enter’ on a line of code. What environment does this activate?