I’ve been out of the computer world for ages. During those ages, I’ve got a bunch of ideas. I’ve chosen Phoenix/Elixir (over Flutter/Dart/Google) to prototype most of 'em quickly.
Although the core apps will be written using/in Phoenix/Elixir, I still find myself running to ruby for small scripts, cli apps, 'n such for more personal, smaller thingies, most of which ai does for me. After having gone through configuring every LSP (the “ruby” vs extension turned out to be the oldest; shopify’s extension for some reason wasn’t listed [dat archlinux life] and gave me troubles; solargraph works but requires extra steps), I wondered, maybe I should just use elixir for scripting everything too? In contrast, Elixir’s LSP worked perfectly on the first try.
does elixir make sense for small scripts? or does the functional-ness make it feel clunky or overkill? since there’s iex, I’m guessing there’s already an interpreter…
it makes sense to invest in one language/library, not two…
having made some tiny games (<3 haxe), I feel comfort in any non-functional object-oriented lang, but perhaps over-time, I’ll be able to think functionally and use elixir for scripting too?..
is everyone here writing their little everyday scripts in elixir? Were there times one even had to reach for ruby?
The only important thing to keep in mind when running these scripts (mainly with escript) is the fact that there is always a quite substantial delay when it starts, because it always spins a new VM instance.
Running them by hand should make no difference, however if you plan on using them in some automated fashion, this becomes a bottleneck very fast.
This is not a interpretation issue per-say, because .exs files are also interpreted, but more of a performance problem of the VM when starting up.
From my understanding the penalty comes from the fact that application supervision tree starts all processes synchronously, this is a great feature for developers, because you don’t have to think about race conditions, but the price is performance.
At the same time I might be wrong and it is just something that will be fixed in the future, currently it doesn’t have a wide impact because most of the elixir applications work as long-running daemons.
Scripting doesn’t have anything to do with it, Ruby and Python have bootstrapping time that I find unacceptable as well as Erlang’s / Elixir’s. They all need time to get going.
For scripting I use bash / zsh if it’s something quick / one-off, or reach for Golang if I suspect I’ll use the tool regularly and need logic that bash / zsh make difficult to code (and sadly they have a lot of foot guns).
It’s “per se” btw.
Many of us would wet their pants if the BEAM has CLI parameters that would allow it to boot much faster (maybe at the cost of initializing apps slower? no idea), trust me. There was a discussion some months ago about it and there were various options listed even by core Erlang maintainers but none of them truly helped.
I think it would be nice, however I think this is not the right tool for CLI applications, at least not in the fashion of run this command and close.
I’ve had this problem before on a project, and what I ended up doing is to switch the strategy to a long-running process, that basically receives input and generates the output without closing the process, but of course there are many potential problems with this approach.
I think one of the solutions we can employ that will work currently would be to have a runtime started and run the scripts in the fashion livebook does, solves the problem and doesn’t require expensive and hard work from VM maintainers.
In that case it was not possible, the CLI was just a wrapper for a custom binary parsing library that we had to use on another project that was written in node, and it was easier from the perspective of infrastructure to ship it as a CLI and not as another service.
IMHO other tools definitely have better options for the sorts of scripts I find myself writing, although I tend to reach for sed, awk or sh (and occasionally perl) rather than ruby. By the time a script approaches something more like an ETL then I’m going to be writing a mix task, although nowadays I’ll be seriously considering livebook.
I’ve experienced two problems with elixir scripting 1) slow startup time 2) lack of ‘getch’. If neither of these matter to you, then Elixir is great for scripting! Check out Ratatouille a very nice TUI toolkit for Elixir.
wow, so many replies! thanks everybody. i def got the feeling of validation that i was perhaps wanting. i guess I felt uncertain of using such old langs, or worse, starting to use an old language, especially when a more contemporary one is right here, but it’s cool to find out languages/libs don’t die. I wish the lispers may lisp forever.
err, maybe the title should have been “should elixir replace scripting languages”? it didn’t have to be ruby. Python, perl, lisp/emacs, lua?, whatever! Glad to know everyone has their own little tool-kit though . just not bash/sed/awk
ratatouille def feels more complicating, lol, but thanks! I’ll look into it again once i’m deep into elixir mode.
unfortunately, I come from the gaming world, so I don’t know any standard library too well. just game engines. The engine decided the language I had to use. I just pray ai isn’t choosing an outdated ruby lib .
in general, the probably best tool choice for CLI apps is Golang.
It allows for very simple and straightforward imperative code, so upgrading from bash scripts is a rather easy experience. It also bundles most things you might need right away in the stdlib, and there also are great libraries (like cobra for more sophisticated CLI stuff). Then it also compiles (instantly) into a standalone binary with zero dependencies needed, and can cross-compile to target architectures right out of the box. Not to mention performance is really good and it feels snappy to use such tools.
However, I personally would like to use Elixir more for scripting, but there are … issues. I think the whole coding experience of nontrivial things is much better and gets very noticeable when things get complex, and you can spin up a nice LiveView UI if needed ontop of everything. My dealbreaker is not the coldstart speed at all, since I would use it for nontrivial things that are running a while to begin with, and when you need to do API calls during the task its a different story altogether, here its more important to have a “renderer” process in parallel that shows realtime update about the current task progress.
What is the core issue for me is the distribution part. I need to give a tool to users that don’t have elixir (or any of its deps) installed at all, like a fresh macbook from a designer or a windows box of an office clerc, both are capable only of clicking a file I send them in terms of setup complexity. Thats like the absolute primary use case for my scripting. Distant second is ssh’ing a script to a server and ./run it there, but this is kinda the same issue again: standalone distribution.
coming from a devops background, this one (missing) feature is absolutely stellar to unlock “scripting” in a broad sense. Go is made for that in a perfect way, python/ruby had the advantages of being preinstalled on certain setups so it was good as long as you didn’t need external dependencies or a specific language version.
anything from elixir releases to escript files are good for sharing stuff with developers - but those are perfectly capable of git clone a repo to begin with (and often prefer it), so these are non-options.
I think the inclusion of go is out of scope here, since it is impossible to do scripting in golang.
You need to have the precompiled binaries for the correct architecture and you will never be able to edit the source files on the target system (since you don’t have them ), which IMO is the whole idea of using scripts and not entire applications.
One possible approach would be to have a script launcher that passes the env, script and standard file descriptors to a semi-persistent Erlang VM (using Unix domain sockets to transfer them to the Erlang VM) the VM can be already started and waiting for script launchers to connect and the launcher would start the VM if it’s not already running. That way you wouldn’t face VM startup delays on every invocation but you do have the script parsing overhead and even that could be reduced with some code caching land cache busting logic.
The launcher would take care of controlling terminal aspects and signal the VM to exit/hup the Erlang script process.
I’m sure there are a few more technicalities like needing module namespace separation between scripts but that may be eliviated with dynamic per script module prefixes.
The worst outcome would be needing to fork the VM but hey KDE does that using a single init process that it forks to eliminate intolerable app startup times due to the number of libraries and symbols that need to be resolved by the library loader.
Just spit balling but doesn’t seem like Mt Insurmountable.
I use Elixir for scripting all the time. Of course you don’t want Elixir for tools such as ls or tree or grep, and for tools that you want to start very fast (like a note taking CLI app for instance).
But for all custom scripts that have something to do with the filesystem, or call to HTTP Apis, the scripts are easy to write, to test and to debug.
If you are going to use that script only 100 times but spend 1 hour instead of 3 to write it then you win against the BEAM startup time. mix test take some time to start, but ExUnit is great, it’s worth it, and honestly it’s not that slow anyway.
I love using Elixir for scripting because I can develop in it much faster than all other options, it has everything in stdlib and hex packages I need, and I don’t care about ~300ms boot times for interactive CLI apps.
I am also very interested in Elixir scripting, and love the single file Mix.install exs examples. The cold boot imo could be solved if there was an elegant way to setup/teardown multiple mix projects in a single beam instance.
As example, even livebook has to setup a new dedicated beam instance for every notebook with its own Mix.install. The UX is amazing imo and would like to scale it for automated app idea.
for that particullar use case of small scripts i’ve been using babashka as a way to keep practicing clojure.
you define the dependencies in the actual script(like you would do in a elixir script with Mix.install), and once you have the dependencies installed, it’s way faster than a elixir script to start once it’s optimized for this type of script.
and you can install babashka with asdf-vm