Hacker News new | past | comments | ask | show | jobs | submit login

Fundamentally it is more like tcl (function chaining) than like bash (process chaining), where process pipelining is the central operation, and where functions and programs are equivalent. In that sense, it has mostly the advantages but also the inconveniences of tcl, javascript and similar non-shell scripting languages. My opinion is that they have quite missed the ball in bash on non-nestable arrays when they introduced them quite recently, but besides that, bash is still pretty much my favourite tool.



Yes, in writing my bash parser/interpreter (see below) I explored the non-nested arrays and assoc arrays issue.

I think it mainly has to do with the fact that bash has no references and garbage collection. When you create an array like [1, 2, [a, b]] in Python/Ruby/Perl, you are introducing the concept of references, as well introducing hte potential for reference cycles.

In contrast, an array in bash is just a value, and it took me awhile to figure out how to even copy it. None of these work:

    a=('x y' z)

    b=${a}
    b=${a[*]}
    b=${a[@]}

    b="${a[*]}"
    b="${a[@]}"

    b=( ${a} )
    b=( ${a[*]} )
    b=( ${a[@]} )

    b=( "${a}" )
    b=( "${a[*]}" )
This works:

    b=( "${a[@]}" )
In other words, it takes 11 characters to properly copy an array! This syntax is horrible.


What's more horrible about it is that the simpler sh constructs are somehow not respected in bash culture.

In sh, each function has a local array, and you use that array with "$@". And typically you can get along with only that array. Not so bad.

    my_b() {
        somefunc foo "$@" bar
    }


I think someone needs to write bash the good parts. It is easy to get into a mess because bash wasn't really designed with modular programming in mind. I very often fall back to using files and exported environment variables to pass information between scripts which isn't that great. I still prefer it to ruby or python or some other scripting language because as you said pipes are very convenient.


I'm actually working on that... My viewpoint is that sh is semantically a nice and useful language, but it has horrible syntax and bad/old implementations (I've been looking at bash, dash, mksh, and to some degree zsh).

I'm polishing up a very complete shell parser and a less complete interpreter in 10,000 lines of Python. Most of the problem is parsing -- executing is easy once you've done that. It's actually closer to the bash superset than POSIX sh, so it will be able to run many real programs.

I started with 3,000 lines of C++, but felt like I would never finish with that iteration speed. Now that I know the language inside and out, I can port it back to C++. There are 3,000 lines of tests in a custom test framework which can run against any sh implementation.

I have a few blog posts planned ... if anyone is interested in a link send me an e-mail with subject line "new shell: me@example.com" (address in profile)

I discovered a lot of interesting things about the language and its implementations, like:

- It's actually 4 languages/parsers interleaved, which I call: command, word, arithmetic, boolean (boolean is [[ which is the "compile time" version of [). Then there are some tiny sublanguages like glob and X{a,b}Y brace expansion.

- It can be parsed preetty completely up front, in one pass. Current implementations tend to defer parsing of the stuff inside ${a} $( ) and $(( )) etc. for subsequent passes. They interleave parsing and execution.

But there's only one situation where parsing really depends on execution -- indexing of assoc arrays vs arrays (${a[X] vs ${A[X]). This is in contrast to Make and Perl, which both interleave parsing and execution.

- places where the POSIX spec is stricter than implementations. All implementations accept 'echo 1 >out.txt 2 3' in addition to 'echo 1 2 3 >out.txt', but the POSIX grammar doesn't allow this.

- places where the POSIX grammar is more lenient than bash. The POSIX grammar allows functions defs with a single statement, without {}, like:

    $ dash -c 'f() echo hi; f'
    hi
But bash doesn't allow this.

There are a whole bunch of other things but I will save them for the forthcoming blog.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: