Hacker News new | ask | show | jobs
by aidanhs 4116 days ago
For a long time I couldn't figure out why moving from bash to Python felt like such a big leap, and it was quite frustrating (path manipulation is particularly difficult).

Recently I discovered a post [1] which touches on this:

> The whole point of short code is saving human bandwidth, which is the single thing in a computing environment that doesn't obey Moore's law and doesn't double once in 18 months. Now, which kind of bandwidth is the most valuable? I'll tell you which. It's the interactive command bandwidth.

It makes the argument that syntax is actually really important in building an interactive language - '[]' is better than '()', ' ' is better than ','. And it's true, bash (and, as it happens, tcl) ruthlessly pursue this - strings don't require quotes, function calls just require spaces (rather than brackets and commas) and there's generally very little punctuation for the most common operations.

I bring this up because it's interesting to see bish has gone in the other direction (curly braces, semicolons, brackets, quoted strings) in the name of a 'modern feel'. It makes me wonder if there's a way to bring the power of python (etc) into the shell in a syntax-friendly way.

[1] http://yosefk.com/blog/i-cant-believe-im-praising-tcl.html

5 comments

I tend to write shell scripts in Ruby even more often than bash. I'm proficient in both, but I find that the larger the script, the more I'm affected by the lack of language support in bash, and the many oddities such as the many problems with quoting and string splitting and the hacks/special mechanisms needed to work around them.

Even though bash has some "modern" features, they're typically a bit weird and hard to remember: bash has arrays, for example, but the syntax is bizarre; you can write functions, but you can't declare the parameters, only access them as $1, $2, etc.; and so on. Occasionally I have to look up some expression syntax (like which bracket syntax to use for arithmetics, or whether "if" should have one or two brackets, and whether it's [[ a && b ]] or [[ a ]] && [[ b ]]) just because it's so damn different. It's painfully obvious that bash wasn't planned; so much of its evolution can be felt in the layers of hacks.

And with Ruby it's much easier to refactor to do things like logging (eg., when spawning a sub-command, only show its output if it fails), or provide cleanup (express your script with the command pattern, with commands that know how to commit and undo themselves), or use existing libraries.

Ruby's syntax — the ability to omit parantheses, the support for running shell commands with backticks — makes it particularly suited. For example:

    if [ -e ./somefile ]; then
      ./somecommand ./somefile
      (cd ./somedir && make)
      installdir=`getsomeconfig`
      cp build/mybinary $installdir/bin
    fi
In Ruby:

    if File.exist? "somefile"
      `./somecommand ./somefile`
      Dir.chdir 'somedir' do
        `make`
      end
      installdir = `getsomeconfig`
      cp "build/mybinary", "#{installdir}/bin"
    end
The last line requires that you initially do:

    require 'fileutils'; include FileUtils
Now you have a bunch of utilities (cd, cp, mv, mkdir, mkdir_p, etc.) as global Ruby methods.
Bash sucks when it comes to arrays. Last week I had to change the 'input field separator' because bash arrays are kinda-sorta-but-not-really space delimited, which causes problems where elements have whitespace. I then had to revert the IFS immediately after the required operation, as that screwed something else up later in the script.

I like bash scripting, but the moment to use another language for a script for me is "will this require an array?"

The semantic value of that punctuation is primarily for readibility and comprehensibility, then, where human bandwidth is way more limited. Achieving this goal is much more critical than reducing keystrokes, IMO. "Code is for humans to read, execution is an afterthought" or whatever the famous quote is. This isn't simply included to achieve a "modern feel".
IIRC Brian Kernighan said that. And the Kernighan & Pike book regards the shell, not C, as the primary language of Unix.
Check out Batsh (which "compiles" to Bash *.bat):

Editor: http://batsh.org/

Source: https://github.com/BYVoid/Batsh/

Interesting notion! I personally am not a fan of whitespace sensitivity, but I understand why many people are. For me, after spending years writing code with curly braces and semicolons, they are effectively invisible (and thus do not seem to waste my "human bandwidth").

That being said, the choice to include those syntax features in bish was made entirely to make writing a parser easier, not for any deep philosophical reason.

>was made entirely to make writing a parser easier

That's called optimizing bish developer bandwidth, rather than optimizing bish user bandwidth. Neither requires philosophy :)

I wouldn't exactly call it "modern". It seems like csh++ while avoiding its mistakes by having Bash as the backend.