Higher-order Shell
conway.rutgers.edu
conway.rutgers.edu
xdvi =(curl http://www.diku.dk/~andrzej/papers/RC.dvi)
Yet another reason why you should switch to zsh today :)More about expansions in zsh: http://zsh.sourceforge.net/Doc/Release/zsh_13.html
xdvi <{curl http://www.diku.dk/~andrzej/papers/RC.dvi}
Another reason why you should have changed to rc shell 10 years ago tmp :: (FilePath -> IO ()) -> (Stream -> IO ())
Transforms file-accepting function to work on an input stream.
'keep' is a bit more ambiguous, but I think it's more clear if you write it instead as keep :: IO a -> IO [()]
which has parallels to 'repeat :: a -> [a]' and suggests that the first action will be "kept" and repeated periodically, throwing away the output. At this point, you have to guess when it repeats, but since you provide 'keep' no further information, blocking until files update is a pretty logical guess.tmp: http://conway.rutgers.edu/~ccshan/wiki/blog/posts/Higher-ord...
keep: http://conway.rutgers.edu/~ccshan/wiki/blog/posts/Higher-ord...
In my opinion, since 'keep' takes a function which is, in general, fully capable of any effectful action, it necessarily is of the type
keep :: IO a -> ...
but since it's roughly ignoring any potential return 'a', yet still evaluating the function repeatedly, the best type is something like keep :: IO a -> IO [()]Anyway, if I were going to use Haskell-style type signatures in an article about shell scripts written in Perl, I would probably skip the whole typeclass and monad concept, and just say something like:
keep :: Action -> Action
This doesn't say much about the infinite nature of the process, unfortunately, but modeling effects as though they are pure functions just gets you into trouble anyway. His textual description is much more natural and easier to understand.Anyway, I like articles that combine both Perl and Haskell :) They make me feel less insane.
He's right. There is, for example, rc (the Plan 9 shell, made in 1989).
The following is from section 10, "Pipeline branching" of: http://plan9.bell-labs.com/sys/doc/rc.html
"< or > followed by a command in braces causes the command to be run with its standard output or input attached to a pipe. The parent command (cmp in the example) is started with the other end of the pipe attached to some file descriptor or other, and with an argument that will connect to the pipe when opened (e.g., /dev/fd/6)."
$ cmp <(old) <(new)
(only the braces differ). The author of the article describes a case in which the command in question (unlike cmp) cannot read its input from a pipe such as this, namely xdvi. So for instance
$ cat file.dvi | xdvi
or
$ xdvi <(file.dvi)
would not work due to the nature of xdvi, but one could use
$ cat file.dvi | tmp xdvi
as a shorthand for
$ cat file.dvi > /tmp/blah $ xdvi /tmp/blah $ rm /tmp/blah
(of course using cat this way would be stupid, but suppose that the file data is going to stdout via a command such as curl, as in the article, and it becomes non-trivial).
I really like the characterization of these commands as sort of second-order and I like the 2 new ones offered here (although I try not to get too addicted to command line features that aren't going to be around when I'm hopping from server to server).