Re: My "Stop Using (and Teaching) C-Shell and Tcsh" Page

"Beni Cherniavsky" <[email protected]> Sun, 23 Dec 2007 01:56:09 +0200
Newsgroups gmane.culture.hackers.israel
Message-ID <[email protected]>
On Oct 21, 2007 8:07 PM, Shlomi Fish <shlomif-ik1l9ssToec+JF/[email protected]> wrote:
> On Saturday 20 October 2007, Beni Cherniavsky wrote:
> > I find any shell following Bourne shell semantics of quoting and
> > variable expansion inherently broken, because it takes too much hassle
> > to write correct code.  IMMV.
>
> Can you give some examples for that? And if so - how is FISH better?
>
You CAN do anything in sh, but it's defaults are bad, which makes you
use convoluted syntax or give up and write code with bugs.

Consider this fish code:
{{{
set files (ls)         # splits on \n, creates array
for f in $files        # space-safe!
    cp $f ../backup/$f~   # space-safe
end
ls -l ../backup/$files~   # space-safe, adds backup/...~ around each word!
}}}

The best equivalent POSIX sh code I can come up is much uglier (by
"equivalent" I mean working in the same way; there are easier ways to
do it but I wanted examples of specific shell constucts):
{{{
IFS=$'\n' files=($(ls))
for f in "${files[@]}"; do
    cp "$f" ../backup/"$f"~
end
files2=("${files[@]/#/../backup/}")
ls -l "${files2[@]/%/~}"
}}}
Note especially the syntax for simple one-element-one-word expansion
of an array variable: {{{"${files[@]}"}}}
In fish you just write {{{$files}}}!

However, I was now pleasantly surprised that bash, when not in POSIX
mode, has saner defaults nowdays!
You can remove most of the quotes in the above code.  Just {{{$*}}} or
{{{$@}}} now works like {{{"$@"}}}.
Still, the fact {{{$files}}} only gives the first element of an array,
so you have to write {{{${files[@]}}}} :-(.

Fish makes array variables the default, with scalar variables just
being a special case.
And fish's behaviour of adding prefixes and suffixes to each word
(treating variable expansion like brace expansion) is extremely
convenient.

There are many more small cleanups in the syntax:
* Minimalistic command expansion syntax: {{{(command)}}}.  LISPers rejoice!
* Simplified loop and conditionals syntax -- no {{{then}}} or
{{{do}}}, single {{{end}}} kw.
* Simplified special chars: \n and the like recognized outside quotes.

In many ways fish unifies various special cases to a single generic feature.
* My favorite example is {{{%job}}}.  In bash, some builtins such as
fg or kill special-case this syntax.
  In fish, it's expanded to the pid by the shell, so it's useful in
any command: {{{pstree %1}}} works!
* This goes for user interface as well as syntax.

See http://fishshell.org/user_doc/design.html for more nice principles
behind fish.
The bottom line is that fish's design is compact and elegant, without
dirty baggage.
This appeals to me very much.  It's very possible that my impression
is subjective.

-- 
Beni Cherniavsky <[email protected]> (I read email only on weekends)