5 ms·
Shells are what people use every day, so it's tempting to make more out of it. grep, sed and awk are clumsy tools, but they are more "within the reach" than pyt
by xiaq 13y ago
Shells are what people use every day, so it's tempting to make more out of it. grep, sed and awk are clumsy tools, but they are more "within the reach" than python or ruby.
Also, you miss one particularly elegant aspect of shell programming: the pipeline. It's a powerful facility of concatenative programming, but most people haven't realize it. Try to write "find . -name '*.py' | xargs cat | wc -l" in other languages. You end up either with some parentheses or intermediate variables or a loop, and in any case, much longer code.
- UNIXgod 13y agoYeah UNIX philosophy rocks! It's weird that they want a system shell and it not be POSIX. I don't need support for index arrays in a system shell interpreter. Even erlang can be a shell and wrap around the system toolset making your basic shell scripts work concurrently. For everyday usage the core ash shell is perfect for scripting and zsh csh or korn for interactive usage.
- nfoz 13y ago> For everyday usage the core ash shell is perfect for scripting In my experience, most people have great difficulty correctly writing a simple loop to renames a set of files in a directory. I sumultaneously appreciate UNIX philosophy, and think the shell can be much improved by moving away from POSIX.
- stormbrew 13y agoThe omission wasn't because I'm unaware, believe me. Maybe I just consider it so thoroughly fundamental as to be not worth noting. This is where some of the warts on a higher level than syntax come in, though, to be fair. Your example above fails in confusing -- and maybe even dangerous, depending on the command at the end -- ways if there's spaces in the filenames. One thing I would like would be a more rigid sense of arguments vs. strings and how they come out of such situations. Having to add -print0 to find and --null to xargs to make it safe for that situation is tedious and unfriendly.
- xiaq 13y ago> This is where some of the warts on a higher level than syntax come in, though, to be fair. Your example above fails in confusing -- and maybe even dangerous, depending on the command at the end -- ways if there's spaces in the filenames. One thing I would like would be a more rigid sense of arguments vs. strings and how they come out of such situations. Having to add -print0 to find and --null to xargs to make it safe for that situation is tedious and unfriendly. Yes, that's one of the problems I'm trying to solve :) Powershell solves this by having pipelines pass .NET objects, but I found them too heavyweight.
- stormbrew 13y agoAgree that trying to turn it into an object pipeline is way too heavy.
- icebraining 13y ago> Try to write "find . -name '.py' | xargs cat | wc -l" in other languages. import pipe find(name='*.py') | xargs(cat) | wc().lines The implementation of the functions is left as an exercise for the reader, but the syntax is valid. https://github.com/JulienPalard/Pipe https://github.com/JulienPalard/Pipe
- stormbrew 13y ago> The implementation of the functions is left as an exercise for the reader This is kind of the point.
- xiaq 13y agoYes it's possible in Python, but doing that means working against all idioms and zens of Python. Languages are not only about what they make possible, but also about what they encourage.
- MatmaRex 13y agomap, fold and filter can approximate the pipeline pretty well. Personally I only use shell scripting when I actually want to record a set of commands I ran (or, well, when working in a shell); in all other cases I whip out proper tools. Here's a comparison of code to do the same thing written in Ruby: Dir['**/*.py'].map{|f| File.readlines(f).length }.inject(:+) find . -name '*.py' | xargs cat | wc -l That's 60 characters versus 39 (most of these are just because the "commands" are longer – and I don't think anyone would even try to argue that 'cat' or 'wc' is more readable than 'File.readlines' or 'length'). I ran them on Python 2.7's library directory and my version counted four lines more – I didn't investigate, but I think yours missed lines when cating files without trailing newline. I'd argue that's a bug in your code :)
- xiaq 13y agoThough it's mostly a matter of taste, I find pipelines simpler and more natural than method calls. Compare: xs.filter(p).map(f) with filter p xs | map f (Suppose filter and map are implemented such that they accept input either on the command line or from pipeline.)
- Tyr42 13y agoWell, lets try Haskell syntax map f $ filter p xs what, don't like the reverse order? That's fixable. If we define # as reverse function application, it's xs # filter p # map f or filter p xs # map f which is quite similar to what you are looking for.