I couldn’t agree more. In general I view numerical computing as a strictly harder problem than what people call “general purpose computing”. If you’re doing numerical computing, of course you need to be able to do shell-style programming and string manipulation and I/O and threading. But you also need to be able to crunch numbers quickly and accurately. So Julia is designed to be good at all of those things and great at numerical stuff. Just because I want to multiply some matrices doesn’t mean I don’t want to open files.
I’ve been thinking about a blog post entitled “Julia is a General Purpose Language”. But if you want to write such a blog post first, please do so! It’s more convincing coming from someone less biased.
I confess, I did a lot of Perl and Ruby programming earlier in my life. It was a fairly significant influence on that part of Julia’s standard library design. Some of the earliest Julia blog posts [1] [2] (badly in need of an update, but you can still get what they’re talking about) were about how Julia does shelling out the right way compared to Perl, Ruby, Python, et al. (yes, Python has subprocess but man, that is not a pleasant API compared to Julia’s command objects).
While I would agree with your assessment (in your administrative scripting post) that Julia may not be ideal for administrative scripting because of the heftiness of the runtime, the command API was expressly designed for that kind of thing and I think it’s actually better than any other language, possibly including shells. I had observed that the backticks for shelling out in languages like Perl and Ruby are so convenient and seductive that I would see my colleagues using them all the time but I would always cringe a bit because every time someone splices a file name into backticks in Perl or Ruby, they’re creating a bug/trap that’s just waiting to get sprung by a file name with a space or some other metacharacter in it. I thought, instead of lecturing people on not doing that, how would you design something where the convenient, seductive thing was actually the correct, safe way to call an external process? And thus Julia’s backticks syntax was born. Instead of shelling out and causing all sorts of problems because of leaning on the shell, it implements shell-like semantics itself and avoids all of those problems.
Another benefit from not shelling out to call commands is that Julia’s command API is actually fully portable: it works exactly the same on Linux , Mac, FreeBSD and Windows because it doesn’t rely on an external shell. A shell that will be GNU bash on Linux and macOS but tsch on FreeBSD and won’t exist at all on Windows. Shelling out is one of the largest headaches when people try to port tools between operating systems. Julia doesn’t have that problem. And all of Julia’s I/O is fully portable because we use libuv.
Btw, I’m currently working on a design for adding more shell-like features inside the backtick syntax which will ultimately bring that up to the level of being nearly as capable as a shell. Julia’s backticks will essentially be a fully portable mini shell language, without the control flow and evaluation constructs since you’ve got a full programming language for that outside of the backticks.
This will especially be true once the ongoing threading work is done. After that Julia’s threading model will be essentially the same as Go’s: Julia’s tasks will be the equivalent of Go’s “goroutines”—coroutines that may be run concurrently on different hardware threads. We also try to take it a step further by having distributed programming model that matches the multicore programming model as closely as possible: Channel versus RemoteChannel, etc.