Which is the best way to distribute a software developed in Julia for the general public? I mean, assuming the installation of the Julia interpreter is out of question.
Most specifically, I have a software that performs some heavy calculations, written in Julia, and that is used as a backend in another software that has a simple GUI for Windows.
Normally, I would distribute an executable with static libraries. I understand that this is not possible (yet) with Julia.
I wander if there is a way to package all the functions and routines used by my package and distribute it as a “minimal” Julia interpreter with the package. Even if it is not an executable, this solution would be good enough and could be hidden from the user.
Sadly, there really aren’t any solutions right now for having reasonably sized binaries. It does require ~ 600 MB at least to run any Julia code. The only way around that (in principle) is building static binaries with PackageCompiler, but I don’t know if anyone has managed to get the total binary size much smaller than that.
I don’t think that 1MB is a reasonable expectation for a language like Julia. You may never get binaries the size of C, but for a desktop/productivity program that does something genuinely useful, people should not balk at 1GB these days (for which SSD storage costs about 10 cents, and download takes a few minutes on a wired connection).
I disagree with this sentiment. There isn’t anything (other than explicit calls to eval at runtime) that should stop Julia code from being static compiled to a very small binary. Take a look at the size of CUDAnative kernels; they’re tiny and they can do tons of number crunching. Adapting this approach to native binaries with init logic and a C-callable interface is really all the OP would need to make their project feasible.
Also, let’s please not encourage software bloat just because disk space is getting cheaper. There is no reason why 1GB should be needed for a very small program which is only doing basic number crunching.
I am not sure about this. The complete universe of (parametric) types used is perhaps fixed for some programs in theory, but deriving this in a foolproof manner in practice is a very hard problem. So you need the whole machinery.
f(z::Bar) = rand() > 0.9 ? z : f(Bar(z))
While this is a contrived example, higher-level logic may not be type stable even in well-written Julia programs, especially if they use external input.
People have been complaining about this since the early days of eg Common Lisp (“you need 10MB to do what?”), but as disks are getting cheaper and programmer time remains expensive, expect this trend to continue.
Eg if it takes me an afternoon to shave off 50MB from a program that will run on less than 1000 machines, then working on this would make sense only if I put a very low value on my time.
I won’t disagree with the example you posted; something like that will be hard to deal with, unless we’re somehow able to construct and work with types without doing any codegen (which may be possible by interpreting until we get back to compiled code paths). I’ll keep this example in mind
I get that this has always been the case, but I still find 1GB to be absolutely absurd for a very small program, even by today’s standard. And the fact that static languages like C can make amazingly small binaries with a modern compiler urges me to figure out how to do the same in Julia.
I also place a high value on my time, but I’m also hoping that once written, a Julia static compiler would be able to do this automatically without the developer having to spend any time working on it at all. I certainly wouldn’t want smaller and smaller binaries to require more and more developer time!
Sure, and so we’ll probably need, at a minimum, libc and possibly libjulia for each program. Other than that, there shouldn’t be any required dependencies for very simple programs that don’t make heavy use of the task runtime, BLAS, etc. An example I like to think of is an email filter (milter) that does very simple text wrangling of emails as they are received by a mail server. All that would probably need (in terms of shared libraries) is libc, libjulia, and PCRE.
I feel that it wouldn’t hurt much if the compiler asked the developer which are the types of the parameters for the function calls it couldn’t strictly determine. In static languages we do that while coding, I don’t see why that would be a big issue if one wants a static compiled code.
You’re referring to PackageCompiler binaries, which simply compile your code on top of the sysimage - and that sysimage is, by default, ~170MB on the typical Linux machine. I’m aiming for static compilation like what CUDAnative does for its kernels. Those kernels can be arbitrarily small, probably down to below a single page of memory (4KB) if the kernel doesn’t do anything too complicated. That’s the approach that I plan on taking.