[OT] Haskell-inspired functions for BASH

Hi all, I've been studying Haskell for about a year now, and I've really come to like it. In my daily work I write a lot of BASH shell scripts and I thought I'd try add some of the haskell features and constructs to BASH to make my scripting life a bit easier. So I've been working on a small BASH function library that implements some basic functional programming building blocks. Note: There is no actual Haskell code involved here. All this is very prototypical, but here is an example of some of the stuff I've got so far (map, filter, foldr): $ ls data 1.txt 2.txt # basic map, argument goes on the command line $ ls -d data/* | map basename 1.txt 2.txt # map with lambda expression $ ls -d data/* | map '\f -> basename $f .txt' 1 2 # simple filter, also works with lambda $ ls -d data/* | map basename | filter 'test 1.txt =' 1.txt # sum $ ls -d data/* | map '\f -> basename $f .txt' | foldr '\x acc -> echo $(($x + $acc))' 0 3 Before I continue with this project, I'm looking for a bit of feedback/info: - Does anyone know if there are already similar projets out there? - Does anyone find this interesting? - Any other comment/suggestion/feedback Thanks a lot, Patrick LeBoutillier -- ===================== Patrick LeBoutillier Rosemère, Québec, Canada

Patrick LeBoutillier wrote:
Hi all,
I've been studying Haskell for about a year now, and I've really come to like it. In my daily work I write a lot of BASH shell scripts and I thought I'd try add some of the haskell features and constructs to BASH to make my scripting life a bit easier. So I've been working on a small BASH function library that implements some basic functional programming building blocks.
Note: There is no actual Haskell code involved here.
All this is very prototypical, but here is an example of some of the stuff I've got so far (map, filter, foldr):
$ ls data 1.txt 2.txt
# basic map, argument goes on the command line $ ls -d data/* | map basename 1.txt 2.txt
# map with lambda expression $ ls -d data/* | map '\f -> basename $f .txt' 1 2
# simple filter, also works with lambda $ ls -d data/* | map basename | filter 'test 1.txt =' 1.txt
# sum $ ls -d data/* | map '\f -> basename $f .txt' | foldr '\x acc -> echo $(($x + $acc))' 0 3
Before I continue with this project, I'm looking for a bit of feedback/info: - Does anyone know if there are already similar projets out there?
Once upon a time, there was the es shell, based on the Unix version of Tom Duff's Plan 9 rc shell, IIRC. It was intended to provide a functional language for shell programming. Never caught on at all, as far as I know, but it might be interesting. http://192.220.96.201/es/es-usenix-winter93.html Looks like there is a Google project for it: http://code.google.com/p/es-shell/
- Does anyone find this interesting?
Yep. :-) Looks pretty cool to me.
- Any other comment/suggestion/feedback
-- Tommy M. McGuire mcguire@crsr.net

Your project is nice. I never thougt about how much effort it is to write cmd | while read f; do basename $f; done cmd | map basename *is* much easier. For now I just put map(){ while read l; do $@ "$l"; done; } into my .bashrc. Having a simple parser which parses the "lambda" funtion to split cols could be interesting. Example ecoh -e "a b\nb c" | map "\1 2 -> echo $2" should output the second col or such. (separating values by spaces or tabs. There are at least two tools which can do this as well: | awk '{ print $2}': or such or man col. Probably there are more tools. The Windows-Powershell even let's you pass objects. However it's command line interface is horrible compared to bash / zsh. But I think they're working on this. Also you could use some Vim tools to workaround this. There was another attempt to create many tools using Haskell. I don't recall the name. Just open hackage and search for "Shell". On the other hand let me tell you what my experience is. I do shell scripting once in a while. However bash/sh sucks if you have to do more complicated things. It can be done but you start fighting with the language or learning details about it you don't want to know. Eg the difference echo "foo" | while ... done in contrast to while ... done <<< "foo" The first one opens a subshell which means if you assign local vars you can't use the results outside of the loop. So additionally to your attempt I highly recommend you learning a scripting language such as Ruby or Python to get some things done. Why do I *not* recommend haskell here? Because compiling scripts will use much disk space (Haskell applications tend to be big) and ghci startup time is bad compared to either Python or Ruby. So you can image than you have to wait 5secs using a pipe like this: echa | app1 | app2 | app3 | app4 just because ghci has to startup and load some libraries. Anyway there are many projects which could server your needs. Eg http://www.focusresearch.com/gregor/sw/psh/ yet another. Before spending much effort on your library I'd spend some time searching the net to see what is available.. Also make sure to search the haskell-cafe mailinglist. I think you'll find some pointers there as well. Whil searching the web don't miss autopager (FireFox plugin). Good luck and thank you for your map shortcut idea! Marc Weber
participants (3)
-
Marc Weber
-
Patrick LeBoutillier
-
Tommy M. McGuire