How to use the preserve keywords in the Pkg REPL? - julia

The behavior of Julia's Pkg, can be specified with the preserve keyword like this:
julia> Pkg.add("Plots", preserve=PRESERVE_DIRECT)
However I prefer to use Pkg REPL. Can I use the same keyword within the REPL?

Yes, that is possible. You can prepend the packages with the --preserve=<tier> flag like this:
pkg> add --preserve=direct Plots
For all tiers of the resolve algorithm, see the documentation.

Related

Equivalent of R's `rm(list=ls())` in Julia

Is there any equivalent to R's rm(list=ls()) (which removes every object in the global environment) in Julia?
It is currently not possible. See Delete full workspace or one variable in julia for the explanation of the current status of the issue (in short - the currently recommended practice is to wrap the code you use in a module and Julia will allow you to replace this module).

Can I %cd to the value of an environment variable directly?

I am using a group of interesting, but not very well written notebooks from a github repository, which occasionally assume a particular path for loading resources.
I want to simply change the current working directory to a path which is in an environment variable.
Yes I can load the os python module. Yes I can use several lines of code to unpack the list returned by !echo $PROJECT_DIRECTORY, and then use %cd. I don't want to exit jupyter and use a command-line argument when I stumble upon this kind of problem. I want the least complex, most readable cell to do the trick.
Is there some syntax that lets me %cd directly to the value of an environment variable? Looking something like:
%cd ${PROJECT_DIR}
P.S. It seems that %env can't use the value of an environment variable, only display it. Am I wrong?
Cheers...
You can do
%env PROJECT_DIR
%cd {_}

Julia doesn't find packages in depot_path anymore

I have a problem with using packages in Julia. It has worked before, and I'm not really sure why this has changed or how to troubleshoot.
I have a folder
/my_path/julia/packages
with Julia packages. For example, there is a folder
/my_path/julia/packages/FFTW/
with the FFTW package.
Further, I have changed the depot path to point at this directory by assigning JULIA_DEPOT_PATH before starting julia, so that
Base.DEPOT_PATH = ["/my_path/julia/"]
However, if I run
julia> using FFTW
I get the following error message:
ERROR: ArgumentError: Package FFTW not found in current path:
- Run `import Pkg; Pkg.add("FFTW")` to install the FFTW package.
Any idea how I can troubleshoot or fix this?
Manipulating Base.DEPOT_PATH does not seem like a good idea.
The code proposed by #cmc will does not work (at least on Julia 1.3.1):
julia> Base.DEPOT_PATH = ["/some/path"]
ERROR: cannot assign variables in other modules
There is a workaround:
Base.DEPOT_PATH[1] = "/some/path"
However, the correct way is to assign the JULIA_DEPOT_PATH system variable before starting Julia, Windows:
set JULIA_DEPOT_PATH=c:\some\path
or
set JULIA_DEPOT_PATH=c:\some\path1;c:\some\path2
Linux/OSX:
export JULIA_DEPOT_PATH=/some/path
or
export JULIA_DEPOT_PATH=/some/path1:/some/path2
Unless you have a specific reason to do so (and if this is the case I'd be interested to hear it!), you don't need to fiddle with the DEPOT_PATH or LOAD_PATH variables: using Julia's package manager should be enough to cover your needs most of the time.
In this specific instance, have you tried to do what the error message suggests?
julia> import Pkg
julia> Pkg.add("FFTW")
LOAD_PATH, not DEPOT_PATH, will modify code loading.
You want to do something like push!(LOAD_PATH, /my_path/julia/packages).
I will echo #ffevotte and strongly suggest to not modify LOAD_PATH unless necessary. The benefits of organizing dependencies into Pkg environments far outweigh the small overhead of declaring them explicitly through Pkg.add.

Sharing Lisp symbols across packages

I have a function foo defined in a package my-package:
(in-package :my-package)
(defun foo (a)
(if (eql a 'value1)
(do-this)
(do-the-other)))
When I call this function from a different package I have to qualify the parameter with the package name:
(in-package :cl-user)
(my-package:foo 'my-package::value1)
but this is rather ugly. I want to share the symbol value1 with all other packages.
I found one workaround which is to import the symbol value1, but this only works if it has been already defined in the other package.
Another possibility is to pass strings, "value1", but again, this is just a patch.
What is the best way to share symbols across packages?
Thanks for your help.
Use a keyword symbol, which you can always write without naming its package keyword:
(foo:bar :value1)
Keyword symbols are in the KEYWORD package, are evaluating to themselves, are automatically exported and you don't need to write down the package name.
Since a keyword symbol evaluates to itself, you even don't have to quote them - but you can.
(foo:bar ':value1)
Alternative: short package names
Sometimes it might be useful to have a symbol in a specific package. Then I would use a short package name, which you can also define as a nickname. See the options on DEFPACKAGE. For example the package color-graphics could have the nickname cg.
Then one would write:
(foo:bar 'cg:green)
Since it is a normal symbol, you have to quote it, otherwise it would be a variable.

Is there a way to run julia script with arguments from REPL?

I can run julia script with arguments from Powershell as > julia test.jl 'a' 'b'. I can run a script from REPL with include("test.jl") but include accepts just one argument - the path to the script.
From playing around with include it seems that it runs a script as a code block with all the variables referencing the current(?) scope so if I explicitly redefine ARGS variable in REPL it catches on and displays corresponding script results:
>ARGS="c","d"
>include("test.jl") # prints its arguments in a loop
c
d
This however gives a warning for redefining ARGS and doesn't seem the intended way of doing that. Is there another way to run a script from REPL (or from another script) while stating its arguments explicitly?
You probably don't want to run a self-contained script by includeing it. There are two options:
If the script isn't in your control and calling it from the command-line is the canonical interface, just call it in a separate Julia process. run(`$JULIA_HOME/julia path/to/script.jl arg1 arg2`). See running external commands for more details.
If you have control over the script, it'd probably make more sense to split it up into two parts: a library-like file that just defines Julia functions (but doesn't run any analyses) and a command-line file that parses the arguments and calls the functions defined by the library. Both command-line interface and the second script your writing now can include the library — or better yet make the library-like file a full-fledged package.
This solution is not clean or Julia style of doing things. But if you insist:
To avoid the warning when messing with ARGS use the original ARGS but mutate its contents. Like the following:
empty!(ARGS)
push!(ARGS,"argument1")
push!(ARGS,"argument2")
include("file.jl")
And this question is also a duplicate, or related to: juliapassing-argument-to-the-includefile-jl as #AlexanderMorley pointed to.
Not sure if it helps, but it took me a while to figure this:
On your path "C:\Users\\.julia\config\" there may be a .jl file called startup.jl
The trick is that not always Julia setup will create this. So, if neither the directory nor the .jl file exists, create them.
Julia will treat this .jl file as a command list to be executed every time you run REPL. It is very handy in order to set the directory of your projects (i.e. C:\MyJuliaProject\MyJuliaScript.jl using cd("")) and frequent used libs (like using Pkg, using LinearAlgebra, etc)
I wanted to share this as I didn't find anyone explicit saying this directory might not exist in your Julia device's installation. It took me more than it should to figure this thing out.

Resources