Reality is that you read code a lot more often than you write it. If you have a small throw away script then sure, writing it in bash is a bit less work. However, if it’s a script that I’m going to need to maintain, I’d much rather work with Babashka. As a side note, you can also do (.format (java.text.SimpleDateFormat. "dd/MM/yyyy") (java.util.Date.)). I’ve used that enough times that I don’t really need to think about it.
Yes of course, if you know the language and use it often, that works. All I’m saying is that the more unwieldy a piece of code you might use once per week in a shell script, the more I personally would want something like that in a babashka.misc? namespace where I don’t have to remember where it is, just a catchall of all the good parts from shell :)
I think some of the appeal of shell scripting is the way you can create. You know you need a variable output of a command here, so you do "$()" and you know you need some kind of date so you go read that man page to work out what kind of thing to create, and you test it in an echo a few times in a few different shells so you know you are right as to the usage, and then you commit it.
It’s a conversation with your system more than rote memorization.
But yes, large shell scripts, unless they are just gluing together other programs, are best as programs. You can even use a program to work out some hard logic and output a magic string for a shell case statement to resolve into actions.
Babashka scripts can be developed interactively by connecting the editor to the REPL. You just run bb --nrepl-server and any Clojure editor can connect to it. That’s basically how I write all my scripts now.
I’m not a heavy user, but I first started using Babashka well over a year ago. (after some experience with Clojure in the early days of the language(*)) I used it to replace a build script of about 1000 lines of bash with about 500 lines of Babashka. The result was better in a bunch of different dimensions. There are definitely some rough edges when doing shell scripting style things, but Babashka’s own library has been whittling those away since I started using it. I suspect that trend will continue. I suspect I can go through my script and tear out about 100 lines of helper functions which now have equivalents in Babashka’s core library.
Of course, kludgy things like this can usually be wrapped into a small helper function, and then you never have to deal with them again.
It’s not a language for replacing 5-line bash scripts, but for 100+ line bash scripts it’s almost always going to be a no-brainer. In between, it probably depends on the specifics, and whether it’s likely to grow.
(*) That would have been around 2007-2010. I really enjoyed using Clojure back then, but in the years since my focus has been on systems/kernel/embedded programming, where it’s unfortunately not an appropriate choice.
Good article in general but some of the examples are just ridiculous (saying this as a Java/Clojure user)
fname="backup-$(date '+%Y-%m-%d').zip"
nice, easy, everyone has probably written this dozens of times from memory.
(-> (java.time.LocalDateTime/now)
(.format (java.time.format.DateTimeFormatter/ISO_LOCAL_DATE)))
Well, no. I know how it works, I have used it. Chance of memorizing the exact incantation? Zero.
This is exactly why people write shell scripts. Tasks that should be easy or muscle memory are actually that.
Reality is that you read code a lot more often than you write it. If you have a small throw away script then sure, writing it in bash is a bit less work. However, if it’s a script that I’m going to need to maintain, I’d much rather work with Babashka. As a side note, you can also do
(.format (java.text.SimpleDateFormat. "dd/MM/yyyy") (java.util.Date.))
. I’ve used that enough times that I don’t really need to think about it.Yes of course, if you know the language and use it often, that works. All I’m saying is that the more unwieldy a piece of code you might use once per week in a shell script, the more I personally would want something like that in a babashka.misc? namespace where I don’t have to remember where it is, just a catchall of all the good parts from shell :)
Oh for sure, I think that expanding built in helpers for doing common tasks like that would be a very good idea.
I think some of the appeal of shell scripting is the way you can create. You know you need a variable output of a command here, so you do
"$()"
and you know you need some kind of date so you go read that man page to work out what kind of thing to create, and you test it in an echo a few times in a few different shells so you know you are right as to the usage, and then you commit it.It’s a conversation with your system more than rote memorization.
But yes, large shell scripts, unless they are just gluing together other programs, are best as programs. You can even use a program to work out some hard logic and output a magic string for a shell case statement to resolve into actions.
Babashka scripts can be developed interactively by connecting the editor to the REPL. You just run
bb --nrepl-server
and any Clojure editor can connect to it. That’s basically how I write all my scripts now.I’m not a heavy user, but I first started using Babashka well over a year ago. (after some experience with Clojure in the early days of the language(*)) I used it to replace a build script of about 1000 lines of bash with about 500 lines of Babashka. The result was better in a bunch of different dimensions. There are definitely some rough edges when doing shell scripting style things, but Babashka’s own library has been whittling those away since I started using it. I suspect that trend will continue. I suspect I can go through my script and tear out about 100 lines of helper functions which now have equivalents in Babashka’s core library.
Of course, kludgy things like this can usually be wrapped into a small helper function, and then you never have to deal with them again.
It’s not a language for replacing 5-line bash scripts, but for 100+ line bash scripts it’s almost always going to be a no-brainer. In between, it probably depends on the specifics, and whether it’s likely to grow.
(*) That would have been around 2007-2010. I really enjoyed using Clojure back then, but in the years since my focus has been on systems/kernel/embedded programming, where it’s unfortunately not an appropriate choice.