Can you run (execute) a Julia package in a similar way in which one can execute a Python package or module?

Python has the ability to run a package or module using the -m flag.

Does Julia have a similar mechanism?

The way it works in python is as follows.

You run python3 -m my_package.

my_package is a package (a directory) in the current working directory. (Or elsewhere actually, Python will search the CWD first, before searching other locations defined in PYTHON_PATH.)

If my_package contains the file __main__.py, this file will be run as the entrypoint.

I don’t recall exactly if it needs to have if __name__ == __main__: in it. Probably not? Trying to find the information on this now…

I don’t think you will find the exact same functionality, but you might be interested in:

Can you maybe make more precise what “running a package” should result in?

If it should make all exported functionality available, then this is the same as using MyPackage.

If it is about running some code, like the main part suggests, then the equivalent part would probably be a script file. That is a main.jl file containing Julia commands.
This can then be run on REPL with include("main.jl"); (if you are in the right folder already),
or similarly on the command line with julia main.jl

1 Like

Yes, in Julia 1.12 -m works in Julia too:

$ julia +nightly -m LiveServer --help
NAME
       LiveServer.main - run a webserver

SYNOPSIS
       julia -m LiveServer [-h <host>] [-p <port>] [-v] [--help] <directory>

DESCRIPTION
       `LiveServer.main` (typically invoked as `julia -m LiveServer`)
       starts a web server serving the contents of the specified
       filesystem directory using the LiveServer.jl Julia package.

OPTIONS
       <directory>
           Path to the root directory of the server (default: pwd)
       -h <host>
           Specify the host (default: 127.0.0.1)
       -p <port>
           Specify the port (default: 8000)
       -v
           Enable verbose output
       --help
           Show this message
12 Likes

This looks promising - could you share a documentation link if you have one? I’m not familiar with this.

Possibly because this has only been added recently? Perhaps even as recently as the last few weeks?

This was added in Julia 1.11, I believe (via Main entrypoint take 3 - revenge of the macro by Keno · Pull Request #51435 · JuliaLang/julia · GitHub)? Sorry, wrong PR — the -m flag is indeed new in 1.12, see below.

See the Main.main entry point in the manual. (Though I find the current docs on this to be a little obscure, TBH.)

Do either of those pages mention -m? If either does, I can’t find it…

Oh, sorry, the -m flag to execute Module.main was added in Introduce -m/--module flag to execute a `main` function in a package by KristofferC · Pull Request #52103 · JuliaLang/julia · GitHub, which is new in Julia 1.12.

On the other hand, you should be able to do

julia -e 'import MyPackage; MyPackage.main(ARGS)'

on any Julia version, no?

1 Like

Am I correct in thinking the way to use this is to:

  • define a file MyPackage.jl
  • which lives inside MyPackage/src/
  • which also defines
function (@main)(ARGS)

end

This information I found from

It does not seem to be documented or mentioned explicitly in the PR thread.

BTW, this is tangential. Someone commented on that thread stating that it is better to have separation between executable definitions and libraries.

I used to also think this way, but actually there is a better argument.

  • Library code inside packages is not that different from executables
  • Rephrased: where is the boundary between executables and libraries?

One could consider two extremes:

  • Every executable is a minimal main function which just bootstraps a package
using MyPackage

function (@main)(ARGS)
    MyPackage.run(ARGS)
end
  • or: Every package is designed to be as general as possible, good examples of which are datetime utils, calendar utils, and math libraries.

Clearly none of these examples can be an executable. (What function should it perform? Return todays date? Add 1 and 2? It doesn’t make sense because they are general purpose.)

In the case of the former it is clear what function it should perform, but the package has no generality. It does one business logic thing that it was designed to do, and nothing else.

The latter is actually very difficult to achieve in general, unless you are writing a package/library, and this your entire objective. You don’t intend to use it or write an application using it.

(Please use your imagination a bit here.)

Generally speaking, as soon as you move even slightly towards the realm of developing a production application, you tend to end up with library code which is not pure library code but some mix between code which is domain specific to your exact use case and context, and code which is “pure” general purpose libraries. Usually it is more weighted towards the former than the latter.

Python, much to my own surprise I will admit, sometimes, somehow, manages to do things which turn out to be genius design decisions - and I mean this in a literal sense. Whether the authors of those decisions knew what they were doing was genius seems unlikely - or at least if it was they certainly didn’t say so or even document it anywhere.

I suspect actually, like C++ template metaprogramming, these things were discovered rather than designed. Nobody designed C++ templates for sophisticated (although complex and arduous) metaprogramming, but it was discovered that templates and the compiler could be used to perform sophisticated metaprogramming that no one knew was possible until someone discovered how to do it.

The problem in this particular (Python) case is almost nobody - and I mean literally almost nobody - knows how to use Pythons module and package system.

I only happened to come across this information by accident while working for a particular company for a short period of time. I have never seen it openly documented on the internet.