Shell
If the real work can be done with existing utilities.
Bash:
- My default
- Included with Git for Windows
PowerShell:
- Included with Windows
- JSON/XML support
Your user is running Windows. Your user has some combination of settings that will manage to cause your script to fail, so he will need to read through your script and execute the commands interactively, copying and pasting with the mouse to mitigate syntax pain. Your user does not wish to install a new language for every utility you write. Therefore, you should write your programs in a language that is included with Windows and is interpreted rather than compiled. This narrows down your choices to the singleton set of PowerShell.
Though Windows, as mentioned, comes with PowerShell installed by default, it also blocks PowerShell scripts from running by default, so you may have to guide your user through that. Microsoft has obviously assumed that most people will wish to use PowerShell interactively, for which purpose it is a stomach cramp, or they could have just published it to winget and let you install it yourself. Also, the PowerShell included with Windows is ancient, arcane, and wrong; if you want a non-buggy experience, you'll need to install the latest cross-platform PowerShell (which is actually a separate program!) and use that. So PowerShell is installed by default with Windows, except that it isn't, and is primarily used interactively, for which it is no good, and is best for scripting, which is disallowed by default. And if you just run your scripts using the default installation to avoid installing anything, you'll still need Internet access to look up the command to allow scripting, because, instead of something simple like "chmod +x", it's "Set-ExecutionPolicy -Bypass", or possibly one of three or so other arguments instead of "Bypass", the difference between which escapes me at the moment. And you'll have to assure Windows that, yes, you know what you are about and would like to use their scripting language for Windows to run scripts on Windows.
The high practicality of running PowerShell, combined with the low practicality of writing it, is one of the best arguments I have heard for the use of AI.
Interpreted (non-shell)
Interpreted languages need installed to run, so I rarely ship them to others. I write my personal utilities either in Bash or in compiled languages. The result is that I almost never write programs in interpreted languages. I know Python and have programmed in Ruby, but I haven't found a non-educational use for either.
On the other hand, if someone else has written a program in an interpreted language, installation and continued updates are very easy for you. Just clone the Git repository somewhere useful and add "cd <source directory> && git pull" to your update script for each program.
Node.js:
- Programmers probably have it installed already.
- JSON support if jq is insufficient
- Native regex support
Perl:
- Native regex support
- Easy for reading and writing files
- Included with Git for Windows
- Doesn't induce guilt like JavaScript since no one uses Perl anymore
awk: Line-by-line file transformations, I guess?
Compiled
I compile to native code and ship an executable. I don't do runtimes.
C99: Default choice
C#:
- JSON/XML support
- Needs an IDE by design
- Verbose
- Opinionated about all the wrong things
F#:
- Can do (almost) anything C# can do
- Can define functions without first making a class to put them in
- Syntax almost as concise as Python, and sometimes much more so
- Union types with exhaustive matching so that switches finally just work
- Everything is like writing a pipeline of transforms in Bash. This is by design.
Of these three languages, everything today is written in C#. It has the tools. Who wants to go back to C? But when you try C after programming in C# for a long time, the first thing you notice (in your starting main.c, before you have started to worry about CMake, malloc, or header files) is the sudden calm. The shouting in your head has stopped. You suddenly know where everything is. When you say that you need a FooStruct, C allocates you a FooStruct, no constructor call needed. When you allocate some memory, you know exactly what goes into it. You don't have to remember which static manager class you put that function in because there are no qualifiers or namespaces of any sort. Or classes. Functions go where you put them. You can do funky things with enum case values without fear. You control everything. The world is yours.
It's addicting. I'm addicted.
F# is what you use to lose half the pain of C# while keeping the conveniences. Except that no one ever uses it because we're all used to programming in C# and switching syntaxes is hard. And, after a few years, C# will halfheartedly steal any idea it can with a new feature. You'll have to learn a new syntax, but you will suddenly have one fewer splinter in your foot, and all will be well with the world and with C#. The new feature won't work as well slapped onto C# as it did in F#, where it has existed from the early versions, but who will know? So we will all just continue to use C#, telling ourselves that it's just as good as F# now, which lie we will preserve so long as we do not spend an afternoon remembering how to use F# and recalling its true rhythm.